Являются ли распределительные атомные группы регулярными?

Являются ли распределительные атомные группы регулярными?

т.е. (?>A?B?) всегда эквивалентно (?>A?)(?>B?)?

Если нет, укажите пример.

Ответ 1

Атомные группы вообще

  • Атомная группа (?>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?). Таким образом, если мои рассуждения верны, для этого специального случая, совпадения будут одинаковыми для нескольких необязательных атомных групп как единая атомная группа с обоими необязательными компонентами.

Ответ 2

Поскольку вы не указали, я предполагаю, что вы ссылаетесь на регулярные выражения 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,...) были бы разными.