В чем разница следующих регулярных выражений?
(\2amigo|(go!))+
(amigo|(go!))+
Они оба соответствуют одним и тем же строкам. https://regexr.com/3u62t
Как работает прямая ссылка?
В чем разница следующих регулярных выражений?
(\2amigo|(go!))+
(amigo|(go!))+
Они оба соответствуют одним и тем же строкам. https://regexr.com/3u62t
Как работает прямая ссылка?
На самом деле это вообще не работает (хотя, как заметил Виктор Стрибижев, это могло бы быть с другими вариантами регулярных выражений).
Когда \n
относится к группе захвата, которая ничего не захватила, это соответствует пустой строке. Вы можете увидеть это, например. /(a)?b\1/
, что соответствует b
.
Когда \n
относится к группе захвата, которая появляется позже в шаблоне, обычно она еще ничего не захватила. Вы можете увидеть это, например. /\1b(a)/
, что соответствует ba
.
Вы можете подумать, что при повторении предыдущие захваты сохраняются, так что /(\2a(b))*/
соответствует abbab
, но это не так: при повторении, когда начинается новое совпадение, захваты сбрасываются. Вместо этого он соответствует abab
, не abbab
.
В результате прямая ссылка полностью и совершенно бесполезна и соответствует только пустой строке. Между двумя вашими шаблонами нет никакой разницы.
Второй "(amigo|(go!))+" захватывает: amigoamigo
Первый "(\2amigo|(вперед!))+ " не работает.
Поведение зависит от языка.
В Ruby и Perl также можно использовать прямые ссылки, но убедитесь, что ссылочная скобка совпала, когда она будет использоваться. Обычно это означает, что прямая ссылка находится внутри некоторой группы повторов. Например, в Ruby это регулярное выражение совпадает с train
только в том случае, если перед ним стоит хотя бы один префикс 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
пусто):