regex - Как вы используете выражение 'nth capturing group' (\ n) в Lookbehind? - PullRequest
0 голосов
/ 12 июля 2019

Есть ли способ использовать выражение 'nth capturing group' (то есть '\ 1', '\ 2', '\ 3' и т. Д.) В виде регулярного выражения Lookbehind?

Примерно так: (?<=\1)([a-z])

Я знаю, что его можно использовать в Lookahead: ([a-z])(?=\1)

Я тестирую свои шаблоны регулярных выражений с помощью онлайн-инструмента, и он постоянно выдает мне ошибки всякий раз, когда я использую выражение '\ n' в Lookbehind.

Это заставляет меня думать, что либо требуется специальный синтаксис, либо это просто невозможно.

Если действительно невозможно использовать выражение '\ n' в Lookbehind, есть ли альтернативы, которые будут работать так же хорошо?

Редактировать: Моя цель - иметь возможность динамически проверить наличие символа перед текущим персонажем.

Мой конкретный вариант использования заключается в том, что я ищу все символы, которым не предшествует ни один и тот же символ, за которым они стоят.

Например, с учетом этих строк:

// Should match 'b', because it is neither followed nor preceded by a 'b'.
// Should match 'd' for the same reason
aabccd 

// Should match 'y'
xxyzz

// Should match 'l' and 'o'
lmmmnnopppp

Я подумал, что лучший способ сделать это - сопоставить все символы, используя ([a-z]), но выбрать только те, которым не предшествовал один и тот же символ, используя (?<!\1), и за которыми не следовал один и тот же символ, используя: (?!\1).

Полный шаблон будет выглядеть примерно так: /(?<!\1)([a-z])(?!\1)/g

Однако, если выражения 'nth capturing group' не могут быть использованы в утверждениях Lookebehind, и нет эквивалентной замены, тогда мне придется искать другую стратегию.

1 Ответ

2 голосов
/ 12 июля 2019

Если вы изучите это регулярное выражение (a.*).+?(?<!\1)..
, вы увидите, что группа захвата 1 может иметь переменную длину.

Итак, большинство движков регулярных выражений, которые поддерживают только фиксированной ширины
, смотрят за утверждениями, не позволяют использовать обратную ссылку
внутри взгляда за утверждением.Даже если группа захвата фиксирована (a)
, она все равно не позволит вам это сделать.


Альтернатива может варьироваться от случая к случаю, но обычно она включает в себя использование прогнозного утверждения.


Fwiw

(?<=\1)([a-z]) прямо эквивалентно(?<=([a-z]))\1

обновление

Редактировать: Моя цель - иметь возможность динамически проверять наличие символа перед текущимсимвол.

Мой конкретный вариант использования заключается в том, что я ищу все символы, которым не предшествует или за которыми не следует тот же символ, что и у него.

Вы можете сделать эти два почти идентичныхпути.
Они оба включают в себя дополнительную проверку для границы
на взгляд позади, взгляд в будущее не проблема.

Большинство людей не знают, что вы можете вставлять / вкладывать утверждения
, и они очень эффективны в изменении направления проверки
, фактически работая в отдельном стеке с
его собственным кодом.положение и все.

Это позволяет вам делать такие хитрые вещи, как это:

Способ 1 - Использование сброса ветви (?| )
ничего особенного, просто используются общие группы захвата.
Просто читать легче.Требуется PCRE или Perl или Ruby.

(?|(?<=\b()(?=([a-z])))\2(?!\2)|(?<=([a-z])(?!\1)(?=([a-z])))\2(?!\2))

https://regex101.com/r/s6Z8uV/1

Расширенное

 (?|
      (?<=
           \b 
           ( )                           # (1)
           (?=
                ( [a-z] )                     # (2)
           )
      )
      \2 
      (?! \2 )
   |  
      (?<=
           ( [a-z] )                     # (1)
           (?! \1 )
           (?=
                ( [a-z] )                     # (2)
           )
      )
      \2 
      (?! \2 )
 )

Способ 2 - Использование ничего особенного.

(?:(?<=\b()(?=([a-z])))\2(?!\2)|(?<=([a-z])(?!\3)(?=([a-z])))\4(?!\4))

https://regex101.com/r/D0lTUF/1

Расширенное

 (?:
      (?<=
           \b 
           ( )                           # (1)
           (?=
                ( [a-z] )                     # (2)
           )
      )
      \2 
      (?! \2 )
   |  
      (?<=
           ( [a-z] )                     # (3)
           (?! \3 )
           (?=
                ( [a-z] )                     # (4)
           )
      )
      \4 
      (?! \4 )
 )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...