Почему (. *) * Делает два совпадения и ничего не выбирает в группе $1?
Это связано с обсуждением формализации синтаксиса регулярных выражений. Я видел это поведение с несколькими синтаксическими анализаторами регулярных выражений, поэтому я отметил его язык-агностик.
Возьмите следующее выражение (отрегулируйте его для вашего любимого языка):
replace("input", "(.*)*", "$1")
он вернет пустую строку. Почему?
Более любопытно, выражение replace("input", "(.*)*", "A$1B")
вернет строку ABAB
. Почему двойное пустое совпадение?
Отказ от ответственности: Я знаю об отступах и жадных матчах, но правила, изложенные Джеффри Фридл, говорят, что .*
соответствует все, и что дальнейшее отступление или сопоставление не производится. Тогда почему $1
пусто?
Примечание: сравните с (.+)*
, который возвращает строку ввода. Однако http://regexhero.com показывает, что есть еще два совпадения, что кажется странным по тем же причинам, что и выше.
Ответы
Ответ 1
Посмотрим, что получится:
-
(.*)
соответствует "input"
.
-
"input"
записывается в группу 1
.
- Механизм regex теперь расположен в конце строки. Но поскольку
(.*)
повторяется, делается другая попытка совпадения:
-
(.*)
соответствует пустой строке после "input"
.
- Пустая строка записывается в группу
1
, перезаписывая "input"
.
-
$1
теперь содержит пустую строку.
Хороший вопрос из комментариев:
Тогда почему replace("input", "(input)*", "A$1B")
возвращает "AinputBAB"
?
-
(input)*
соответствует "input"
. Он заменяется на "AinputB"
.
-
(input)*
соответствует пустой строке. Он заменяется на "AB"
($1
пуст, потому что он не участвовал в матче).
- Результат:
"AinputBAB"