Являются ли распределительные атомные группы регулярными?
т.е. (?>A?B?)
всегда эквивалентно (?>A?)(?>B?)
?
Если нет, укажите пример.
Являются ли распределительные атомные группы регулярными?
т.е. (?>A?B?)
всегда эквивалентно (?>A?)(?>B?)
?
Если нет, укажите пример.
Атомные группы вообще
Атомная группа (?>regex1|regex2|regex3)
принимает в ней только первое успешное совпадение. Другими словами, он не позволяет отступать.
Регулярные выражения оцениваются слева направо, поэтому вы выражаете порядок, который вы намерены сопоставить. Двигатель запускается в первом положении, пытаясь сделать успешное совпадение, при необходимости отступив назад. Если какой-либо путь через выражение приведет к успешному совпадению, он будет соответствовать в этой позиции.
Атомные группы не являются дистрибутивными. Рассмотрим эти шаблоны, оцененные с помощью ABC
:
(?>(AB?))(?>(BC))
(нет совпадений) и (?>(AB?)(BC))
(соответствует ABC
).
Атомные группы со всеми необязательными компонентами
Но ваш сценарий, когда обе части являются необязательными, может отличаться.
Учитывая атомную группу с 2 жадными дополнительными частями A и B ((A)?
и (B)?
). В любой позиции, если A
соответствует, он может перейти, чтобы оценить необязательный B
. В противном случае, если A
не соответствует, это прекрасно, потому что оно необязательно. Поэтому (A)?
соответствует любой позиции. Эта же логика применяется для необязательного B
. Остается вопрос, может ли быть какая-либо разница в отступлении.
В случае всех необязательных частей ((?>A?B?)
), поскольку каждая часть всегда соответствует, нет причин для возврата в атомную группу, поэтому она всегда будет соответствовать. Тогда, поскольку он находится в атомной группе, запрещается отступать.
В случае отдельных атомных групп ((?>A?)(?>B?)
) каждая часть всегда соответствует, и в любом случае движку запрещается обратное отслеживание. Это означает, что результаты будут одинаковыми.
Чтобы повторить, двигатель может использовать только первое возможное совпадение в (?>A?)(?>B?)
, которое всегда будет совпадать с первым возможным совпадением в (?>A?B?)
. Таким образом, если мои рассуждения верны, для этого специального случая, совпадения будут одинаковыми для нескольких необязательных атомных групп как единая атомная группа с обоими необязательными компонентами.
Поскольку вы не указали, я предполагаю, что вы ссылаетесь на регулярные выражения Perl, так как я не видел оператора группировки (?>)
на любом другом языке.
Рассмотрим следующее:
ra = 'A?'
rb = 'B?'
/(?>${ra} ${rb})/x
совпадает с /(?>${ra})(?>${rb})/x
.
В этом случае, да, это работает в любом случае; однако, поскольку (?>)
отключает обратное отслеживание, это не относится к некоторым другим значениям ra
и rb
.
Например, данный:
ra = 'A*'
rb = 'AB*'
/(?>${ra} ${rb})/x
!= /(?>${ra})(?>${rb})/x
.
В последнем случае rb никогда не может сравниться, так как ra будет потреблять целую последовательность A, и не позволит отступать. Обратите внимание, что это сработает, если мы будем использовать (?:)
в качестве оператора группировки. Заметим также, что если бы мы использовали группы захвата ()
, то совпадение было бы одинаковым, но побочные эффекты (назначение \1
, \2
,...) были бы разными.