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

295
24 июня 2017, 13:43

Доброго времени суток! У меня есть регулярка, предназначенная для поиска форм одного и того же слова в строке. Эти регулярки автоматически генерируются для каждого слова и получаются довольно длинными, но создаются по одному шаблону. Например нужно создать регулярку для поиска форм слова "кот". Берём "базовую" часть регулярки:

(^|[^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 + ">"; })

Этот вариант почти работает, выдавая такой результат:

"бла бла< кот >бла бла <"кота"> бла< коты >скоты"

Но как можно видеть, он "захватывает" внутрь скобок кавычки и пробелы. Подскажите, как в данной ситуации организовать корректную замену? Заранее спасибо!

Несколько важных замечаний:

  1. Я не могу использовать модификатор \b так как в движке регулярных выражений в JavaScript этот модификатор корректно работает только с латинскими буквами (у меня как правило кириллические тексты)
  2. Примерно по той же причине я не могу пользоваться именованными группами - в Js-регулярках они не поддерживаются
  3. Сами регулярки несколько упрощены в демонстрационных целях, например, в них нет буквы "ё" и прописных букв.
  4. Возможно тут указаны не все формы слова "кот", в данном примере это не столь важно
Answer 1

Всех своих котов сложите во вторую группу захвата

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>'));

Answer 2

Вот пример регулярки для вашего вопроса, и для примера я немного изменил пример вашей строки, и все в точности делает так как вы хотите:

let str = 'бла бла кот бла &котик* sksdfk котенок бла "кота" бла коты скоты'; 
 
let res = str.replace(/([a-zа-яё]*кот[a-zа-яё]*)/gi,'<$1>'); 
 
console.log(res);

READ ALSO
wordpress function.php не работает easing.min.js

wordpress function.php не работает easing.min.js

Скрипт 'freelancerjs' зависит от 'easingjs', при явном объявлении в футере все хорошо работает, но через правильное объявление в functionphp, 'easingjs' не срабатывает...

329
Кеширование ресурсов с CDN при помощи sw-precache

Кеширование ресурсов с CDN при помощи sw-precache

Пытаюсь сгенерировать сервис-воркер при помощи sw-precache, который должен кешировать внешние ресурсыС кешированием ресурсов, которые лежат...

235
Условие вывода массива PHP

Условие вывода массива PHP

В общем, есть массив с которого я вывожу данные на страницуДля первого выведеного элемента из массива, мне нужно сделать блок 'div' "Активным"

362
Обрезка строки php

Обрезка строки php

Простенький вопрос, но не могу сформулировать для гугла есть строка number_id=1, она может быть number_id=100 или number_id=10 мне нужно получить числовые...

283