我正在尝试使用
preg_replace()
来清理写得不好的 XML。
$x = '<abc x="y"><def x="g">more test</def x="g"><blah>test data</blah></abc x="y">';
逻辑是检查结束标签内是否有空格
</ >
并删除从空格到标签末尾的所有内容。
想要的结果:
<abc x="y"><def x="g">more test</def><blah>test data</blah></abc>
这应该可以做到:
preg_replace('/<\/(\w+)\s*[^>]*>/', '</\1>', $x);
在这种情况下,正则表达式实际上可能是可行的:
$xml = preg_replace("#(</(\w+:)?\w+)\s[^>]+>#", "$1>", $xml);
编辑:根据@netcoder的提示修复。在垃圾之前强制添加空格。
明显的陷阱当然是注释(对于数据 XML 来说不太可能)和 CDATA 部分(从 xml 的外观来看也不太可能)。
虽然您仍然可以尝试 QueryPath,但它应该也可以使用 XML,并且可能对这些情况具有弹性。怎么就乱码了?
preg_replace('/<\/(.*?)\s+[^>]+>/', '</$1>', $string);
编辑:经过测试,有效。
尝试:
preg_replace("/<\/((\w)([^<].*)?)\>/","</$2>",$x);
代码未测试
您还可以使用 T-Regx 库:
以@Jonah 为例:
pattern('<\/(.*?)\s+[^>]+>')->replace($string)->all()->withReferences('</$1>');
PS:请注意,使用
with()
会引用占位符。
将结束标记的前导部分与
</\w+
匹配,然后用 \K
忽略这些字符,然后将后跟零个或多个非大于符号的文字空格与 [^>]*
匹配,然后向前查找文字结束带 (?=>)
的大于符号。 用空字符串替换该匹配项。 (演示)
$x = '<abc x="y"><def x="g">more test</def x="g"><blah>test data</blah></abc x="y">';
echo preg_replace('#</\w+\K [^>]*(?=>)#', '', $x);
// <abc x="y"><def x="g">more test</def><blah>test data</blah></abc>