正则表达式只返回带管道符的标签

时间:2014-05-06 12:48:34

标签: php regex

我正在努力让正则表达式工作。

我有一些不好的XML,我不得不做一些预处理,因为有些标签中包含一个或多个管道字符。我想在将它传递给simplexml_load_string()进行解析之前将它们删除。

XML的一大块看起来像这样:

<ALERTNOTEACTIONS>0</ALERTNOTEACTIONS>
<ALLOW|DELIVERY|EDIT>1</ALLOW|DELIVERY|EDIT>
<ALLOW|OVERBOOKING>1</ALLOW|OVERBOOKING>
<ALLOWCASHMOVEMENTSWHENCLOSED>1</ALLOWCASHMOVEMENTSWHENCLOSED>

我需要删除“|”管道标签中的字符,但仅在内部内容中留下任何管道字符。

我需要的是/<([\/A-Z|]+)>/i的反转,只返回包含管道的标签,然后我使用preg_replace来替换标签。花了几个小时浏览正则表达式的例子,我看不出如何只需要一个或多个管道字符的所有标签,或者我错过了一些非常简单的东西?

任何更好的替代方案也将受到赞赏。

2 个答案:

答案 0 :(得分:1)

您想用标签替换标签?是不是通常推荐用于工作的PHP的XML操作工具(例如http://www.php.net/manual/fr/refs.xml.php),处理错误的XML?


作为一个(非常有限的)正则表达式解决方案,要根据您的输入将标签与管道匹配,可以采用简单的方法:

<[^><|]*+\|[^><]*+>

[^><]表示除了><之外的任何内容,它会阻止正则表达式转到实际标记的外部。

使用*+possessive quantifier,将允许正则表达式失败并更快地继续前进。

如果您有<foo|bar bar="1>3" >(因为它匹配<foo|bar bar="1>)或<foo|bar bar="1<3" >(不匹配)等内容,这会中断,但如果您没有看到这些内容就足够了案例(如您的示例所示,请参阅demo)。

答案 1 :(得分:1)

我不确定你想用标签内的管道做什么,但如果你的目标是从“标签名称”中删除它们,你可以使用它:

$xml = preg_replace('~(?:<|(?!\A)\G)[^>|\s]*+\K\|~', '', $xml);

我假设属性(<AAA attr="|||">)内的管道不是问题,这就是从字符类中排除\s的原因。