我在字符串中有这个标签:
<?xml:namespace prefix = o /?>
如何使用PHP和regex从字符串中删除那些和类似的标签?
我试过了:
$clean = preg_replace('/<\?xml[^>]+\/>/im', '', $dirty);
答案 0 :(得分:1)
该字符串中的内容为Processing Instruction (PI, see XML 1.0)。
如果要从未使用PCRE UTF-8修饰符进行UTF-8编码的字符串中删除这些PI,可以使用以下模式:
~
<\?
(?: [A-Za-z_:] | [^\x00-\x7F] ) (?: [A-Za-z_:.-] | [^\x00-\x7F] )*
(?: \?> | \s (?: [^?]* \?+ ) (?: [^>?] [^?]* \?+ )* >)
~x
它是从 a REX expression for XML Processing Instructions 到PHP中使用的PCRE表达式的翻译。
代码示例:
$str = "some string <?xml:namespace prefix = o /?> that is";
$pattern = '~
<\?
(?: [A-Za-z_:] | [^\x00-\x7F] ) (?: [A-Za-z_:.-] | [^\x00-\x7F] )*
(?: \?> | \s (?: [^?]* \?+ ) (?: [^>?] [^?]* \?+ )* >)
~x';
echo preg_replace($pattern, '', $str);
输出:
some string that is
与之前给出的答案不同的是,这个正则表达式确实......
?>
&#34;)。特别是&#34; >
&#34;可以在处理指令中使用。xml
&#34;开头。仅值得一提的有关限制的一些注意事项:
<?xml
&#34;开头。同样。这可以通过在打开&#34; <?
&#34;之后不查找XML保留名称来更改。像#34; (?! [xX][mM][lL] (?: \?> | \s ) )
&#34;。由于这些限制,可能值得考虑
首先,使用PHP strip_tags
来删除处理指令要容易得多。它也会删除其他标签和评论。这可能并不总是需要,它只是非常直接:
strip_tags($str)
更明确的是,正则表达式和strip_tags
都使用PHP附带的XML解析器之一来去除处理指令。例如PHP的DOM扩展。它可以包装在一个函数中,以便轻松应用于字符串:
dom_strip_pis($str)
这样的示例性函数也适用于您使用保留名称&#34; xml
&#34;的XML字符串。作为XML中实际上不正确的前缀。但解析器不会呛到它:
/**
* remove processing instructions from an XML string
*
* @author hakre <http://hakre.wordpress.com>
*
* @param string $xml
* @return string
*/
function dom_strip_pis($str) {
$doc = new DOMDocument;
$fragment = $doc->createDocumentFragment();
$saved = libxml_use_internal_errors(true);
$fragment-> appendXML($str);
libxml_use_internal_errors($saved);
foreach($fragment->childNodes as $node) {
if ($node instanceof DOMProcessingInstruction) {
$node->parentNode->removeChild($node);
}
}
return $doc->saveXML($fragment);
}
使用上一个示例中给出的XML解析器不会让您处理浅层解析。
答案 1 :(得分:0)
你非常接近 - 请注意&#39;?&#39;在收盘角括号前的最后:
<?xml:namespace prefix = o /?>
为了匹配它,你需要这个:
<?php
$clean=preg_replace('/<\?xml[^>]+\/\?>/im', '', $dirty);
?>