Я получил следующую ситуацию:
...
preg_match('/#(.+?):(.+?)#/im','partA#partB#partC:partD#partE#partF',$matches);
...
после выполнения $ match становится
Array
(
[0] => #partB#partC:partD#
[1] => partB#partC
[2] => partD
)
Разве это не нормально для $matches[1]
становиться partC
если я использую не жадный шаблон ?
? Я что-то пропустил?
Мне удалось решить это с помощью '/#([^#]+?):([^#]+?)#/im'
как образец, все же подходящее объяснение было бы здорово очистить облака.
Благодарю.
Это имеет смысл, когда вы думаете о теории, лежащей в основе регулярных выражений.
Регулярное выражение — это то, что известно как конечный автомат (FSA). Это означает, что он, по сути, будет обрабатывать вашу строку по одному символу за раз слева направо, иногда возвращаясь назад, «отказываясь» от символов. В вашем примере регулярное выражение видит первый #
и, отмечая, что #
не участвует ни в каких других частях шаблона, начинает сопоставлять следующий токен (.+?
, в твоем случае). Это происходит до тех пор, пока не попадет в двоеточие, а затем не найдет следующий токен .+?
). Поскольку он идет слева направо, он соответствует первому хешу, а затем останавливается, потому что он ленивый.
Это на самом деле распространенное заблуждение — ?
модификатор для квантификатора не нежадным, его ленивый. Это будет соответствовать минимально возможной строке, идти слева направо.
Чтобы исправить свое оригинальное регулярное выражение, вы можете изменить его следующим образом:
/.+#(.+?):(.+?)#/im
Для этого нужно использовать жадное совпадение перед последним хешем перед двоеточием, заставляя первую группу захвата использовать только то, что находится между этим хешем и двоеточием. В том же духе этой группе также не понадобится ленивый модификатор, дающий окончательное регулярное выражение:
/.+#(.+):(.+?)#/im
Группа захвата 1 ищет #
тогда что-нибудь (исключая новые строки) до первого :
, Так partB#partC
имеет смысл.
Ваши модификаторы тоже ничего не делают. У вас нет букв, чувствительных к регистру, и вы не используете якоря.
Вы можете увидеть, как ваше регулярное выражение обрабатывает здесь, https://regex101.com/r/iS0lW9/1.