Прямая ссылка в регулярном выражении

В чем отличие следующих регулярных выражений?

(\2amigo|(go!))+
(amigo|(go!))+

Они оба соответствуют одинаковым строкам. https://regexr.com/3u62t

Как работает прямая ссылка?

3 ответа

На самом деле он вообще не работает (хотя, как отметил Виктор Стрибьев, он может работать с другими разновидностями регулярных выражений).

когда \n относится к группе захвата, которая ничего не захватила, соответствует пустой строке. Вы можете увидеть это, например, в /(a)?b\1/, который соответствует b,

когда \n относится к группе захвата, которая появляется позже в паттерне, обычно она еще ничего не может захватить. Вы можете увидеть это, например, в /\1b(a)/, который соответствует ba,

Вы можете подумать, что в повторении предыдущие захваты сохраняются, так что /(\2a(b))*/ будет соответствовать abbab, но это не так: в повторении, когда начинается новое совпадение, захваты сбрасываются. Так что вместо этого это соответствует ababне abbab,

В результате прямая ссылка полностью и совершенно бесполезна и всегда соответствует пустой строке. Там нет разницы между вашими двумя шаблонами.

Второй "(амиго |(вперед!))+" Захватывает: амигоамиго

Первый "(\2amigo|(вперед!))+" Не работает.

Поведение зависит от языка.

В Ruby и Perl также можно использовать прямые ссылки, но убедитесь, что указанные скобки совпадают, когда они будут использоваться. Обычно это означает, что прямая ссылка находится внутри некоторой группы повторений. Например, в Ruby это регулярное выражение соответствует только в том случае, если перед ним стоит хотя бы один префикс. choo:

      $ irb
irb(main):052:0> regex = /(\2train|(choo))+/
=> /(\2train|(choo))+/
irb(main):053:0> 'choochootrain' =~ regex
=> 0
irb(main):054:0> $&
=> "choochootrain"
irb(main):055:0> $1
=> "chootrain"
irb(main):056:0> $2
=> "choo"
irb(main):004:0> 'train' =~ regex
=> nil

В JavaScript этого не происходит:

      [~/.../github-actions/225-github-actions-demo(master)]$ node
Welcome to Node.js v13.5.0.
Type ".help" for more information.
> regex = /(\2train|(choo))+/
/(\2train|(choo))+/
> regex.exec('train')
[
  'train',
  'train',
  undefined,
  index: 0,
  input: 'train',
  groups: undefined
]

На самом деле это соответствует train\2 считается пустым):

Другие вопросы по тегам