【发布时间】:2011-11-23 04:34:24
【问题描述】:
我偶然发现了一个与 PHP 的 preg_replace 函数和一些正则表达式模式有关的非常奇怪的错误。我想要做的是替换用括号分隔的自定义标签并将它们转换为 HTML。正则表达式必须考虑将保留在输出 HTML 中的自定义“填充”标签,以便在页面加载时可以即时替换它(例如替换为站点名称)。
每个正则表达式模式都会自行工作,但由于某种原因,如果先检查其他模式之一,其中一些会提前退出函数。当我偶然发现这一点时,我使用 preg_match 和一个 foreach 循环在继续之前检查模式,如果找到就会返回结果 - 所以假设它对每个模式来说都是新鲜的。
这也没有用。
检查代码:
function replaceLTags($originalString){
$patterns = array(
'#^\[l\]([^\s]+)\[/l\]$#i' => '<a href="$1">$1</a>',
'#^\[l=([^\s]+)]([^\[]+)\[/l\]$#i'=> '<a href="$1">$2</a>',
'#^\[l=([^\s]+) title=([^\[]+)]([^\[]+)\[/l\]$#i' => '<a href="$1" title="$2">$3</a>',
'#^\[l=([^\s]+) rel=([^\[]+)]([^\[]+)\[/l\]$#i' => '<a href="$1" rel="$2">$3</a>',
'#^\[l=([^\s]+) onClick=([^\[]+)]([^\[]+)\[/l\]$#i' => '<a href="$1" onClick="$2">$3</a>',
'#^\[l=([^\s]+) style=([^\[]+)]([^\[]+)\[/l\]$#i' => '<a href="$1" style="$2">$3</a>',
'#^\[l=([^\s]+) onClick=([^\[]+) style=([^\[]+)]([^\[]+)\[/l\]$#i' => '<a href="$1" onClick="$2" style="$3">$4</a>',
'#^\[l=([^\s]+) class=([^\[]+) style=([^\[]+)]([^\[]+)\[/l\]$#i' => '<a href="$1" class="$2" style="$3">$4</a>',
'#^\[l=([^\s]+) class=([^\[]+) rel=([^\[]+)] target=([^\[]+)]([^\[]+)\[/l\]$#i' => '<a href="$1" class="$2" rel="$3" target="$4">$5</a>'
);
foreach ($patterns as $pattern => $replace){
if (preg_match($pattern, $originalString)){
return preg_replace($pattern, $replace, $originalString);
}
}
}
$string = '[l=[site_url]/site-category/ class=hello rel=nofollow target=_blank]Hello there[/l]';
echo $alteredString = $format->replaceLTags($string);
上面的“字符串”会变成:
<a href="[site_url">/site-category/ class=hello rel=nofollow target=_blank]Hello there</a>
什么时候出现:
<a href="[site_url]/site-category/" class="hello" rel="nofollow" target="_blank">Hello there</a>
但如果将该模式在列表中进一步向上移动以便更快地检查,它的格式会正确。
我很难过,因为似乎每次检查字符串时都会以某种方式被覆盖,即使这没有意义。
【问题讨论】:
-
你真的想要
return吗?return preg_replace($pattern, $replace, $originalString);应该是$originalString = preg_replace($pattern, $replace, $originalString);这样循环才能继续处理吗? -
我想过这个,德鲁。但是只要没有找到匹配项,foreach 循环就应该继续。如果找到匹配项,您不希望循环继续,这只会浪费 CPU 资源。这就是为什么我告诉它一旦找到就返回。我想让它提取属性名称和值,这样我就可以拥有一个能够回溯标签中所有属性的正则表达式模式(无论类型如何:img、a、p、div、等),但到目前为止我还没有能够让它成功工作。上周我在这上面花了太多时间。
标签: php regex preg-replace