[英]preg_match_all and foreach only replacing last match
我有以下代码,它应该使纯文本链接可点击。 但是,如果有多个链接,它只会替换最后一个。
代码:
$nc = preg_match_all('#<pre[\s\S]*</pre>#U', $postbits, $matches_code);
foreach($matches_code[0] AS $match_code)
{
$match = null;
$matches = null;
$url_regex = '#https?://(\w*:\w*@)?[-\w.]+(:\d+)?(/([\w/_.]*(\?\S+)?)?)?[^<\.,:;"\'\s]+#';
$n = preg_match_all($url_regex, $match_code, $matches);
foreach($matches[0] AS $match)
{
$html_url = '<a href="' . $match . '" target="_blank">' . $match . '</a>';
$match_string = str_replace($match, $html_url, $match_code);
}
$postbits = str_replace($match_code, $match_string, $postbits);
}
结果:
http://www.google.com
http://www.yahoo.com
http://www.microsoft.com/ <-- only this one is clickable
预期结果:
我的错误在哪里?
如果有多个链接,它只会替换最后一个
我的错误在哪里?
实际上,它正在替换所有 3 个链接,但每次都会替换原始字符串。
foreach($matches[0] AS $match)
{
$html_url = '<a href="' . $match . '" target="_blank">' . $match . '</a>';
$match_string = str_replace($match, $html_url, $match_code);
}
循环执行 3 次,每次替换$match_code
1 个链接并将结果分配给$match_string
。 在第一次迭代中, $match_string
被分配了一个可点击的google.com
的结果。 在第二次迭代中, $match_string
被分配了一个可点击的yahoo.com
。 但是,您刚刚替换了原始字符串,因此现在无法点击google.com
。 这就是为什么您只能获得最后一个链接的原因。
您可能还想在代码中更正以下几点:
#<pre[\\s\\S]*</pre>#U
最好构造为#<pre.*</pre>#Us
。 类[\\s\\S]*
通常用于 JavaScript,其中没有s
标志来允许点匹配换行符。https?://\\S+
。 我还将在这里为您提供一些替代方案。preg_match_all()
调用和 1 个str_replace()
调用,您可以将它包装在 1 个preg_replace()
。代码
$postbits = "
<pre>
http://www.google.com
http://w...content-available-to-author-only...o.com
http://www.microsoft.com/ <-- only this one clickable
</pre>";
$regex = '#\G((?:(?!\A)|.*<pre)(?:(?!</pre>).)*)(https?://\S+?)#isU';
$repl = '\1<a href="\2" target="_blank">\2</a>';
$postbits = preg_replace( $regex, $repl, $postbits);
正则表达式
\\G
总是从主题中的第一个匹配位置开始。(?:(?!\\A)|.*<pre)
匹配字符串开头的第一个<pre
标签,或者如果在此标签中找不到更多 URL,则允许获取下一个<pre
标签。(?:(?!</pre>).)*)
使用<pre>
标签内的任何字符。(https?://\\S+?)
匹配 1 个 URL。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.