Прямая ссылка в регулярном выражении
В чем отличие следующих регулярных выражений?
(\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
считается пустым):