PHP preg_replace странность с пользовательскими URL - PullRequest
1 голос
/ 07 января 2010

Я использую следующий код для добавления <span> тегов за <a> тегами.

$html = preg_replace("~<a.*?href=\"$url\".*?>.*?</a>~i", "$0<span>test</span>", $html);

Код работает нормально для обычных ссылок (т. Е. http://www.google.com/),, но он не будет выполнять замену, если содержимое $ url равно $link$/3/.

Это пример кода, демонстрирующий (неправильное) поведение:

<?php
    $urls = array();
    $urls[] = '$link$/3/';
    $urls[] = 'http://www.google.com/';

    $html = '<a href="$link/3/">Test Link</a>' . "\n" . '<a href="http://www.google.com/">Google</a>';

    foreach($urls as $url) {
        $html = preg_replace("~<a.*?href=\"$url\".*?>.*?</a>~i", "$0<span>test</span>", $html);
    }

    echo $html;
?>

И это вывод, который он производит:

<a href="$link$/3/">Test Link</a>
<a href="http://www.google.com/">Google</a><span>test</span>

Ответы [ 4 ]

3 голосов
/ 07 января 2010

$url = preg_quote($url, '~'); знаки доллара интерпретируются как обычно: конец ввода.

2 голосов
/ 07 января 2010

просто кто-то прав; вы должны экранировать свои специальные символы регулярных выражений, если вы хотите, чтобы они интерпретировались как буквальные.

Мне также кажется, что он не может выполнить замену, потому что он никогда не соответствует.

Попробуйте заменить эту строку:

$urls[] = '$link$/3/';

С этим:

$urls[] = '$link/3/';
1 голос
/ 07 января 2010

$ считается специальным символом регулярного выражения и должен быть экранирован. Используйте preg_quote() для выхода из $url перед передачей его в preg_replace().

$url = preg_quote($url, '~');
0 голосов
/ 07 января 2010

$ имеет особое значение в регулярном выражении. Конец линии. Ваше выражение расширяется так:

$html = preg_replace("~<a.*?href=\"$link$/3/\".*?>.*?</a>~i", "$0<span>test</span>", $html);

Что не получается, потому что он не может найти "связь" между двумя концами строк Попробуйте экранировать $ в массиве $ urls:

$urls[] = '\$link\$/3/';
...