Почему * не соответствует *, когда + делает?
В следующих примерах (через regex101.com, режим PCRE) я не могу понять, почему квантификатор + обнаруживает подстроку, но * не делает.
В первой иллюстрации квантор + (1 или более) находит все четыре строчных символа a (что я и ожидал):
![Идентификатор плюса-знака находит 1 или больше, как ожидалось]()
Во второй иллюстрации квантификатор * (0 или более) не находит никаких строчных символов a (что НЕ является тем, что я ожидал):
![Авантификатор Asterisk не находит 0 или более]()
В какой логике REGEX объясняется, почему "1 или больше" (+) находит все четыре строчных символа a, но "0 или больше" (*) не находит?
Ответы
Ответ 1
Механизм regex попытается сопоставить весь шаблон в каждой позиции строки, слева направо. Шаблон /a*/
успешно совпадает с нулем a
в самом начале строки. Это то, что маленькая пунктирная каретка в вашем скриншоте regex101 означает - совпадение нулевой ширины в этой позиции. Это будет больше a
в этой позиции, но их нет. Тем не менее, матч проходит успешно.
Если вы используете функцию, которая возвращает все совпадения регулярных выражений в строке, тогда она будет перемещаться как минимум на один символ каждый раз, чтобы искать новые совпадения, поэтому она будет соответствовать aaaa
(как единый результат), когда она доходит до него. Пример в Python:
import re
regex = r"a*"
input = "AAAAaaaaBBBBbbbb"
print(re.findall(regex, input))
Вывод:
['', '', '', '', 'aaaa', '', '', '', '', '', '', '', '', '']
В то время как при использовании /a+/
он не может выполнять эти совпадения нулевой ширины, поэтому он проходит через вход, пока не найдет свое первое и единственное совпадение в aaaa
.
Ответ 2
Другие ответы уже описывают, что происходит. Но для иллюстрации/примера попробуйте это для размера:
$ echo AAAAaaaabbbb | egrep -o 'a*' && echo "SUCCESS"
SUCCESS
Эффект опции grep -o
заключается в том, чтобы показать вам только часть ввода, которая соответствует регулярному выражению. Так как совпадение оказалось "нулевым символом", результат пуст... но успешный.
Ответ 3
Он фактически соответствует началу строки, где есть нуль a. Если строка начинается с a, она будет соответствовать всем им.
Ответ 4
В начале вы можете увидеть матч!
![Что]()