【问题标题】:PHP preg_replace does not replace normal string with multiple lines [duplicate]PHP preg_replace 不会用多行替换普通字符串[重复]
【发布时间】:2013-04-12 11:01:08
【问题描述】:

我在这里遇到了一个非常奇怪的 preg_replace 问题(据我所知,这不是我第一次看到这个问题)。 我有一个带有无效结构元素的 XML(结束标记缺少斜杠,中断解析器):

<info> 
<datetime>2013.04.12 12:04:02</datetime> 
<info> 

我想要做的是:$xml = preg_replace('/&lt;info&gt;.*&lt;info&gt;/iu', '', $xml)(因为我实际上并不需要那个元素),但它不会替换。
如何让它发挥作用?

【问题讨论】:

    标签: php xml regex


    【解决方案1】:

    尝试将s 修饰符添加到正则表达式规则。不会在新行停止匹配

    【讨论】:

    • 不起作用,返回一个空字符串... err,它返回null
    • @jurchiks 检查源代码:p
    • 什么源代码? var_dump(preg_replace('/&lt;info&gt;.*&lt;info&gt;/ius', '', $response)); => 空
    【解决方案2】:

    它不会替换,因为没有匹配:

    <?php
    
    $xml = '<info>
        <datetime>2013.04.12 12:04:02</datetime>
    <info>';
    var_dump(preg_match('/<info>.*<info>/iu', $xml, $matches), $matches);
    
    int(0)
    array(0) {
    }
    

    让我们看看有什么问题。 What does . mean exactly?

    匹配除换行符以外的任何字符(默认)

    原来如此!你如何更改默认值?我们查看了可用的internal options 并找到了这个:

    s 为PCRE_DOTALL

    ....PCRE_DOTALL means:

    s (PCRE_DOTALL)
    如果设置了此修饰符,则模式中的点元字符匹配所有字符,包括换行符。没有它,换行符是 排除。

    我们可以在本地更改它:

    '/<info>(?s:.*)<info>/iu'
              ^
    

    ... 或全局:

    '/<info>.*<info>/ius'
                       ^
    

    【讨论】:

    • 很好的解释,谢谢!
    【解决方案3】:

    添加s 修饰符并使用? 使其不贪婪:

    $string = '<info> 
    <datetime>2013.04.12 12:04:02</datetime> 
    <info>
    <valid>2013.04.12 12:04:02</valid>
    <info> 
    <datetime>2013.04.12 12:04:02</datetime> 
    <info>';
    var_dump(preg_replace('/<info>.*?<info>/s', '', $string));
    

    【讨论】:

    • 好的,添加 ?工作。谢谢!我可以问为什么它会起作用吗?
    • @jurchiks 所以首先你评论说没有完全阅读你的问题......现在你问为什么它会起作用即使它已经在答案中解释过? .*? 是一种使匹配不贪婪的方法。
    • 答案中没有解释,它只是说“让它不贪婪”。这对我来说没有任何意义,我不是正则表达式大师。查看 Álvaro G. Vicario 的答案,了解一个很好的解释性答案的示例。当然,我得到了我正在寻找的解决方案,但是对它为什么起作用的一个很好的解释不仅对我有好处,而且对以后阅读回复的其他人都有好处。
    • @jurchiks 您编辑了您的评论 waaaaaaaa ! Álvaro G. Vicario 刚刚解释了 s 修饰符的作用,我认为甚至不需要,因为它都记录在 PHP 文档中,老实说,网上有几篇关于 贪婪与非贪婪的文章b>.
    • .* 可以匹配任何东西。 .*a 应该 匹配以a 结尾的所有内容。但是,因为.* 是贪婪的,它也会匹配a,这使得最后没有更多的a 匹配,使其失败。通过使其不贪婪,可以防止这种情况发生。
    【解决方案4】:

    见http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

    您需要在正则表达式的末尾使用 s 修饰符。

    $xml = preg_replace('/<info>.*<info>/ius', '', $xml);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-24
      • 2013-08-10
      • 1970-01-01
      • 1970-01-01
      • 2016-02-17
      • 2019-04-09
      相关资源
      最近更新 更多