我正在努力让正则表达式工作。
我有一些不好的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来替换标签。花了几个小时浏览正则表达式的例子,我看不出如何只需要一个或多个管道字符的所有标签,或者我错过了一些非常简单的东西?
任何更好的替代方案也将受到赞赏。
答案 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
的原因。