PHP preg_replace不会用多行替换普通字符串

时间:2013-04-12 11:01:09

标签: php xml regex

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

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

我要做的是:$xml = preg_replace('/<info>.*<info>/iu', '', $xml)(因为我实际上并不需要那个元素),但它不会替换。
我如何使它工作?

4 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:4)

它没有替换因为没有匹配:

<?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'
                   ^

答案 2 :(得分: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));

答案 3 :(得分:2)

请参阅http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

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

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