Страницы

Поиск по вопросам

вторник, 19 февраля 2019 г.

JavaScript и длинная регулярка

Доброго времени суток! У меня есть регулярка, предназначенная для поиска форм одного и того же слова в строке. Эти регулярки автоматически генерируются для каждого слова и получаются довольно длинными, но создаются по одному шаблону. Например нужно создать регулярку для поиска форм слова "кот". Берём "базовую" часть регулярки:
(^|[^0-9a-zа-я])(кот)([^0-9a-zа-я]|$)
и создаём на её основе полную регулярку для всех форм, склеивая из отдельных частей для каждой формы:
((^|[^0-9a-zа-я])(кот)([^0-9a-zа-я]|$)|(^|[^0-9a-zа-я])(котов)([^0-9a-zа-я]|$)|(^|[^0-9a-zа-я])(котам)([^0-9a-zа-я]|$)|(^|[^0-9a-zа-я])(котами)([^0-9a-zа-я]|$)|(^|[^0-9a-zа-я])(котах)([^0-9a-zа-я]|$)|(^|[^0-9a-zа-я])(коту)([^0-9a-zа-я]|$)|(^|[^0-9a-zа-я])(котом)([^0-9a-zа-я]|$)|(^|[^0-9a-zа-я])(коте)([^0-9a-zа-я]|$)|(^|[^0-9a-zа-я])(кота)([^0-9a-zа-я]|$)|(^|[^0-9a-zа-я])(коты)([^0-9a-zа-я]|$))
Получается такая длинная абракадабра. Возьмём некий текст, в котором встречаются формы слова "кот":
бла бла кот бла бла "кота" бла коты скоты
Мне нужно заменить все вхождения форм слова "кот", ограниченные не словарными символами (пробелами, знаками препинания и тд) на ту же самую форму, обрамлённую угловыми скобками. То есть из исходной строки мне надо получить эту:
бла бла <кот> бла бла "<кота>" бла <коты> скоты
Я это делаю так:
'бла бла кот бла бла "кота" бла коты скоты'.replace(/моя большая регулярка/gi, '$1<$2>$3')
Получается вот что:
"бла бла кот <>бла бла "кота"<> бла коты <>скоты"
Как можно видеть, мой способ не работает - в строке очень много групп (и в каждой строке их разное количество), и поэтому я не могу пользоваться номерами групп при замене - каждый раз мне будут нужны разные номера.
Пробовал использовать такую замену:
'бла бла кот бла бла "кота" бла коты скоты'.replace(/моя большая регулярка/gi, function(match) { return "<" + match + ">"; })
Этот вариант почти работает, выдавая такой результат:
"бла бла< кот >бла бла <"кота"> бла< коты >скоты"
Но как можно видеть, он "захватывает" внутрь скобок кавычки и пробелы. Подскажите, как в данной ситуации организовать корректную замену? Заранее спасибо!
Несколько важных замечаний:
Я не могу использовать модификатор \b так как в движке регулярных выражений в JavaScript этот модификатор корректно работает только с латинскими буквами (у меня как правило кириллические тексты) Примерно по той же причине я не могу пользоваться именованными группами - в Js-регулярках они не поддерживаются Сами регулярки несколько упрощены в демонстрационных целях, например, в них нет буквы "ё" и прописных букв. Возможно тут указаны не все формы слова "кот", в данном примере это не столь важно


Ответ

Всех своих котов сложите во вторую группу захвата
console.log('бла бла кот бла бла "кота" бла коты скоты'.replace(/(^|[^0-9a-zа-яё])(кот|котов|котам|котами|котах|коту|коте|котом|кота|коты)([^0-9a-zа-яё]|$)/gi, '$1<$2>$3'));
UPD для работы с котами идущими через пробел (1 символ):
console.log('котам бла бла кот кот бла бла "кота"кот бла коты скоты котом'.replace(/(^|[^0-9a-zа-яё])(кот|котов|котам|котами|котах|коту|коте|котом|кота|коты)(?![0-9a-zа-яё])/gi, '$1<$2>'));

Комментариев нет:

Отправить комментарий