Почему preg_replace с/(.*)/повторяет часть строки?
Почему следующий код:
<?php echo preg_replace("/(.*)/", "$1.def", "abc");
Вывод abc.def.def
вместо abc.def
?
Мне интересно понять, почему происходит повторение.
Использование /(.+)/
или /^(.*)$/
работает так, как ожидалось, но я не ищу решение, просто задавая вопрос (хотя эти шаблоны могут быть связаны с ответом).
Tinker с живой версией здесь.
Ответы
Ответ 1
Потому что .*
соответствует пустой подстроке в конце строки. Это означает, что в строке abc
есть два совпадения:
- Вся строка
abc
→ abc.def
- Пустая строка →
.def
который дает abc.def.def
.
Изменить: Подробно о том, почему это происходит, объясняется в аномалии String.replaceAll() с жадными квантификаторами в regexя > .
Ответ 2
Ожидаемое поведение: https://bugs.php.net/bug.php?id=53855
Это ожидаемое поведение и ничего особенного для PHP. * квантификатор допускает "пустую" совпадение в конце вашего строка темы.
Ответ 3
Если ваше регулярное выражение не жадное, /(.*?)/
, вы можете увидеть, как весь процесс повторения работает в гораздо большем/заметном масштабе:
.defa.defb.defc.def
Вы получаете четыре матча: a, b, c, empty
. В то время как, как говорили другие люди, с жадным регулярным выражением вы получаете 2 совпадения, полную строку и пустую строку.