RegExp. Найти все совпадения с перекрытием - PullRequest
1 голос
/ 01 октября 2019

Попытка найти все возможные совпадения для цифр, разделенных пробелом. Уже пробуем конструкцию с lookahead и lookbehind, но это не помогает.

У нас есть строка разделенных цифр (0..99).

Нам нужно найти все цифровые последовательности, длина которых больше 3и может содержать специальный символ, например «1».

Символ «1» является универсальным символом и может заменять любую из цифр. Например, '2 2 2 2', '1 2 1 2', '2 1 2 2', '2 2 2 1' - допустимые совпадения.

Все в порядке, кроме таких ситуаций, гдесимвол '1' принадлежит двум совпадениям:

... 2 2 2 2 1 3 3 3 3 ...

Необработанная строка:

3 1 1 4 4 4 4 1 4 4 5 5 1 5 5 6 7 8 1 9 9 9 9 9 9 1 3 4 5 5 1 1 5 5 6 4 4 4 1 7 1 2 2 2 2 2 2 2 1 11 11 11 11 

У моего регулярного выражения все почти нормально, кроме последнего совпадения:

/(1 ){0,}(\d |\d\d )\2{1,}(1 ){0,}\2{1,}(1 ){0,}/g

Текущий результат (см. Последнее совпадение, должно быть '1 11 11 11 11'):

1 1 4 4 4 4 1 4 4 
5 5 1 5 5 
1 9 9 9 9 9 9 1 
5 5 1 1 5 5 
4 4 4 1 
1 2 2 2 2 2 2 2 1 
11 11 11 11 

Цель:

1 1 4 4 4 4 1 4 4 
5 5 1 5 5 
1 9 9 9 9 9 9 1 
5 5 1 1 5 5 
4 4 4 1 
1 2 2 2 2 2 2 2 1 
1 11 11 11 11 

Regexp /(?=((1 ){0,}(\d |\d\d )\3{1,}(1 ){0,}\3{1,}(1 ){0,}))/g дает много вариантов перекрытия.

Здесь песочница: https://regex101.com/r/VDa6LZ/2

Как правильно найти все перекрывающиеся совпадения?

1 Ответ

0 голосов
/ 02 октября 2019

Похоже, что решение , предложенное @ bobblebubble , найдено. Не слишком просто, но решает проблему.

\b(?|(?=(((?:1 )+(\d?\d )\3+(?:1 )*\3+)(?:1 )*))\2|((\d?\d )\2+(?:1 )*\2+(?:1 )*))

Результаты будут в группе 1

  • (?| При использовании сброс ветви , внешние группы по обе стороны трубы будут захвачены как группа 1.
  • (?=(((?:1 )+(\d?\d )\3+(?:1 )*\3+)(?:1 )*))\2 левая сторона чередования предназначена для захвата перекрывающихся 1 частей внутри перспективы. Группа 2 предназначена только для потребления частей до тех пор, пока не начнется последнее вхождение 1, поскольку нам не нужны все подпоследовательности.
  • ((\d?\d )\2+(?:1 )*\2+(?:1 )*) правая сторона предназначена для захвата оставшихся последовательностей.
...