Почему мое регулярное выражение 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 ?";

У меня такое чувство, что его ломает слабая звезда, но я не знаю, как еще сопоставить повторяющиеся ссылки.

Author: rlandster, 2012-05-13

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/

Использование подхода [^]]* будет означать, что входные данные подобраны правильно.

 7
Author: Jarmex, 2012-05-13 13:19:42

Попробуйте это:

$pattern = "/\[(.*?)\]\s?\((.*?)\)/i";

\s? добавлено между \[(.*?)\] и \((.*?)\)

 0
Author: Karo, 2012-05-13 11:31:44