【问题标题】:preg_replace all "_" by spaces only in urlpreg_replace 仅在 url 中用空格替换所有“_”
【发布时间】:2019-06-23 13:30:27
【问题描述】:

我有一个 html 文件,其中包含一些数据,包括一些 url。

仅在这些网址上,我想用空格替换 _ 字符(通过 php 文件)。

所以一个这样的网址:

</p><p><a rel="nofollow" class="external text" href="http://10.20.0.30:1234/index.php/this_is_an_example.html">How_to_sample.</a>

会变成

</p><p><a rel="nofollow" class="external text" href="http://10.20.0.30:1234/index.php/this is an example.html">How_to_sample.</a>

这不会影响不在网址上的_

我认为这可能通过 preg_replace 实现,但我不知道如何进行。

以下代码不正确,因为它替换了每个 _ 而不仅仅是 url 中的那个。

$content2 = preg_replace('/[_]/', ' ', $content);

谢谢。

编辑:

感谢preg_replace_callback 的建议,这正是我想要的。

    // search pattern
    $pattern = '/href="http:\/\/10.20.0.30:1234\/index.php\/(.*?).html">/s';

    // the function call
    $content2 = preg_replace_callback($pattern, 'callback', $content);

    // the callback function
    function callback ($m) {
        print_r($m);
        $url = str_replace("_", " ", $m[1]);
        return 'href="http://10.20.0.30:1234/index.php/'.$url.'.html">';
    }

【问题讨论】:

  • 使用preg_replace_callback 匹配网址,然后在回调中将_s 替换为str_replace(不要对静态字符串使用正则表达式...) .
  • 我在您的示例数据中看不到任何不合格的下划线。我的意思是,看起来您可以安全地替换所有下划线。请更新您的意见,让我代表您的情况。
  • preg_replace_callback 是我正在寻找的!谢谢。
  • 答案不应作为对问题的编辑发布。这不是问答的运作方式。
  • 是的,你是对的,但我无法正确发布答案。我有一条警告消息说我没有权限。

标签: php regex url preg-replace


【解决方案1】:

更老更聪明:不要使用正则表达式 - 这不是必需的,而且它可能容易不稳定,因为正则表达式不支持 DOM。使用 HTML 解析器隔离&lt;a&gt; 标记和href 属性,然后进行简单的str_replace() 调用。

代码:(Demo)

$html = <<<HTML
<p><a rel="nofollow" class="external text" href="http://10.20.0.30:1234/index.php/this_is_an_example.html">How_to_sample.</a></p>
HTML;

$dom = new DOMDocument; 
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
foreach($dom->getElementsByTagName('a') as $a) {
    $a->setAttribute('href', str_replace('_', '%20', $a->getAttribute('href')));
}
echo $dom->saveHTML();

输出:

<p><a rel="nofollow" class="external text" href="http://10.20.0.30:1234/index.php/this%20is%20an%20example.html">How_to_sample.</a></p>

网址不应包含任何空格,空格应编码为%20。 - Is a URL allowed to contain a space?


原答案:

如果您对一些正则表达式技巧持开放态度,您可以单独使用 preg_replace() 完成您的任务。

代码:(Demo)

$input = '</p><p><a rel="nofollow" class="external text" href="http://10.20.0.30:1234/index.php/this_is_an_example.html">How_to_sample.</a>';

$pattern = '~(?:\G|\Qhttp://10.20.0.30:1234/index.php\E[^_]+)\K_([^_.]*)~';

echo preg_replace($pattern, " $1", $input);

输出:

</p><p><a rel="nofollow" class="external text" href="http://10.20.0.30:1234/index.php/this is an example.html">How_to_sample.</a>

\G 是“继续”元字符。它允许您在 url 的预期部分之后进行多个连续匹配。

\Q..\E 说“按字面意思对待两点之间的所有字符——所以不需要转义。

\K 表示“从这一点重新开始全字符串匹配”。

Pattern Demo

由于您正在构建一个 url,我认为您应该替换为 %20

我想我的模式应该拒绝 \G 之后的字符串开头以获得最佳实践...

$pattern = '~(?:\G(?!^)|\Qhttp://10.20.0.30:1234/index.php\E[^_]+)\K_([^_.]*)~';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-11
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    • 2022-06-27
    • 1970-01-01
    • 2012-12-16
    相关资源
    最近更新 更多