PHP:带有模式修饰符的preg_replace()e - 评估结果中的奇怪行为似乎忽略了后向引用

时间:2010-05-27 21:10:51

标签: php regex

请考虑以下情况:我想替换字符串中的链接,特别是我想在其旁边添加“搜索引擎”链接。

思考:链接标题(S),S将以“链接标题”作为搜索词链接到Google。我在代码中复制了一个真实的示例字符串($ content),因此您可以在PHP代码中重现这个1:1。

// PCRE case-insensitive, all as a single string, ungreedy and evaluate PHP replace.
$content = '<h3 class="bgg2" style="padding: 4px 0px 4px 5px; font-size: 11px;">» <a href="/forum_detail.html?topic=3456&amp;start=20&amp;post=97145#p97145" class="nub" title="Xenoblade: Japanischer TV-Spot"><b>Xenoblade: Japanischer TV-Spot</b></a></h3>';

$replace = preg_replace('/(<a.*>)(.*)<\/a>/isUe', ('"\1\2</a>&nbsp;(<a href=\"http://www.google.com/search?q=' . strip_tags(strtoupper('blah\2')) . '\">S</a>)"'), $content);

print($replace);

输出(不正确): Xenoblade:Japanischer TV-Spot(S) - &gt;当您查看HTML时,它看起来像这样:

<a href="http://www.google.com/search?q=BLAH%3Cb%3EXenoblade:%20Japanischer%20TV-Spot%3C/b%3E">S</a>

strtoupper()确实得到了文字字符串blah - &gt; BLAH但不是正则表达式中的\ 2背面参考?

看起来在执行strtoupper()strip_tags()函数之前使用了\ 2后引用字符串 - 某种评估时序与PHP中的函数可能相比?

有人知道如何解释这个bevhaviour吗?

-

我使用preg_replace_callback开发了一种解决方法,但我仍然对上述代码无法正常工作的原因感到困惑。

参考以了解我想要实现的目标:

解决方案

// I have to use PHP < 5.0 so create_function() will do the job.
$replace = preg_replace_callback('/(<a.*>)(.*)<\/a>/isU',
create_function('$matches', 'return $matches[1] . $matches[2] . \'</a>&nbsp;(<a href="http://www.google.com/search?q=\' . strip_tags(strtoupper($matches[2])) . \'">S</a>)\';'),
$content);

print($replace);

输出(正确): Xenoblade:Japanischer TV-Spot(S) - &gt;当您查看HTML时,它看起来像这样:

<a href="http://www.google.com/search?q=XENOBLADE:%20JAPANISCHER%20TV-SPOT">S</a>

2 个答案:

答案 0 :(得分:2)

更改

'"\1\2</a>&nbsp;(<a href=\"http://www.google.com/search?q=' . strip_tags(strtoupper('blah\2')) . '\">S</a>)"'

'"\1\2</a>&nbsp;(<a href=\"http://www.google.com/search?q=" . strip_tags(strtoupper(\'blah\2\')) . "\">S</a>)"'

strip_tags()函数需要是替换字符串的一部分,因此在将其传递给preg_replace()之前不会对其进行评估。

答案 1 :(得分:1)

我认为你混淆了一些事情。在您第一次尝试调用strtoupper()时,它会对传递的字符串起作用。它将采用字符串'blah\2'并将其转换为'BLAH\2'。它不是在处理结果,而是在你的替换模式上。这就像你写的那样......

'"\1\2</a>&nbsp;(<a href=\"http://www.google.com/search?q='  
 . strip_tags('BLAH\2') . '\">S</a>)"'

作为替代模式。