Почему мое регулярное выражение PHP, которое анализирует ссылки на уценку, не работает?
$pattern = "/\[(.*?)\]\((.*?)\)/i";
$replace = "<a href=\"$2\" rel=\"nofollow\">$1</a>";
$text = "blah blah [LINK1](http://example.com) blah [LINK2](http://sub.example.com/) blah blah ?";
echo preg_replace($pattern, $replace, $text);
Вышесказанное работает, но если между [] и () случайно вставлен пробел, все ломается, и две ссылки смешиваются в одну:
$text = "blah blah [LINK1] (http://example.com) blah [LINK2](http://sub.example.com/) blah blah ?";
У меня такое чувство, что его ломает слабая звезда, но я не знаю, как еще сопоставить повторяющиеся ссылки.
2 answers
Если я вас правильно понял, все, что вам действительно нужно сделать, это также сопоставить любое количество пробелов между ними, например:
/\[([^]]*)\] *\(([^)]*)\)/i
Объяснение:
\[ # Matches the opening square bracket (escaped)
([^]]*) # Captures any number of characters that aren't close square brackets
\] # Match close square bracket (escaped)
* # Match any number of spaces
\( # Match the opening bracket (escaped)
([^)]*) # Captures any number of characters that aren't close brackets
\) # Match the close bracket (escaped)
Обоснование:
Я, вероятно, должен обосновать, что причина, по которой я изменил ваш .*?
на [^]]*
Вторая версия более эффективна, потому что ей не нужно выполнять огромное количество отступлений, которое делает .*?
. Кроме того, как только будет обнаружено открытие [
, версия .*?
будет продолжайте искать, пока он не найдет совпадение, а не потерпит неудачу, если это не тег, как мы хотели бы. Например, если мы сопоставим выражение с помощью .*?
с:
Sad face :[ blah [LINK1](http://sub.example.com/) blah
Он будет соответствовать
[ blah [LINK1]
И
http://sub.example.com/
Использование подхода [^]]*
будет означать, что входные данные подобраны правильно.
Попробуйте это:
$pattern = "/\[(.*?)\]\s?\((.*?)\)/i";
\s?
добавлено между \[(.*?)\]
и \((.*?)\)