【问题标题】:php regex replace substringphp正则表达式替换子字符串
【发布时间】:2017-04-20 13:23:39
【问题描述】:

我正在尝试使用 php 正则表达式检测 url,并将所有 &amp 替换为 &。我在所有输入数据中都运行了htmlspecialchars,但我希望 url 可读。我做了这显然不起作用,因为替换部分是错误的。

preg_replace('!(http(s)?://((\S)|(&amp))*)!m', '&', $message); 

基本上,我希望所有字符串保持不变,但在出现在 url 中时更改 &amp。我想使用preg_match_all,但如果数组的值不是通过引用传递的,它将不起作用。

关于我如何做到这一点的任何想法?

【问题讨论】:

  • 它应该是& 而不仅仅是&amp ...虽然我觉得有必要问一下为什么如果这些 URL 被嵌入到你想要替换它们HTML 文档...
  • 您是否有理由不想使用简单的$message = str_replace('&amp', '&', $message);?您还想保留其他&amp 吗?
  • 是的,可能还有更多的转义 & 我不想改变它们
  • CD001 的评论是相关的,如果 url 只是显示在 html 中,你不应该删除它们,如果计划使用 url,最好不要@987654330 @他们作为一个开始。由于不知道这里的全部目标,我们可能会错过更好的解决方案,但作为部分答案,您可以使用 Wiktor Stribiżew 的答案,在回调中使用 htmlspecialchars_decode() 来处理所有替换

标签: php regex replace


【解决方案1】:

您可以使用相对简单的!https?://\S+! 匹配URL(匹配http://https://,然后匹配1+ 个非空白符号)并使用preg_replace_callback 修改每个匹配项中的&amp

$message = preg_replace_callback('!https?://\S+!', function ($m) { 
    return str_replace('&amp', '&', $m[0]); 
}, $message);

查看PHP demo

【讨论】:

    【解决方案2】:

    这可能对你有用:

    preg_match_all('%https?://\S+%msi', $html, $matches, PREG_PATTERN_ORDER);
    
    foreach ($matches[0] as $match)
    {
        $fixed = preg_replace('/&amp/i', '&', $match);
        $match = preg_quote($match);
        $html = preg_replace("@$match@", $fixed, $html);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-17
      • 1970-01-01
      • 1970-01-01
      • 2018-07-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多