Удалить инструкцию обработки (<? Xml тэги и контент) из строки XML
У меня есть этот тег в строке:
<?xml:namespace prefix = o /?>
Как удалить этот и подобные теги из строки с помощью PHP и регулярных выражений?
Я старался:
$clean = preg_replace('/<\?xml[^>]+\/>/im', '', $dirty);
2 ответа
В этой строке есть инструкция обработки (PI, см. XML 1.0).
Если вы хотите удалить те PI из строки, которую вы ожидаете кодировать в UTF-8 без использования модификатора PCRE UTF-8, вы можете использовать следующий шаблон:
~
<\?
(?: [A-Za-z_:] | [^\x00-\x7F] ) (?: [A-Za-z_:.-] | [^\x00-\x7F] )*
(?: \?> | \s (?: [^?]* \?+ ) (?: [^>?] [^?]* \?+ )* >)
~x
Это перевод из выражения REX для инструкций обработки XML в выражение PCRE, используемое в PHP.
Пример кода:
$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
В отличие от предыдущего ответа, это регулярное выражение...
- ... принять закрывающую последовательность ("
?>
") правильно учесть. особенно">
"может быть разрешено в инструкции обработки. - ... не требуется ограничивать имя инструкции обработки, начиная с "
xml
" только. - ... он на самом деле ищет имя как часть вводной последовательности.
- ... имеет дело с пустыми и непустыми инструкциями по обработке.
Некоторые примечания, которые стоит упомянуть об ограничениях:
- Шаблон предназначен для мелкого разбора. То есть, если вы еще не извлекли другие конструкции тега из строки, которая могла бы содержать текст, который снова мог бы выглядеть как такая инструкция обработки (например, блок CDATA или комментарий), тогда шаблон будет соответствовать неверно.
- Шаблон соответствует декларации XML, которая начинается с "
<?xml
"также. Это можно изменить, не ища зарезервированные имена XML после открытия"<?
"с негативным взглядом, как"(?! [xX][mM][lL] (?: \?> | \s ) )
".
Из-за этих ограничений, возможно, стоит рассмотреть
Альтернативы регулярным выражениям
Прежде всего, гораздо проще просто использовать PHP strip_tags
раздеть инструкции по обработке. Он также удалит другие теги и комментарии. Это не всегда нужно, просто очень просто:
strip_tags($str)
Гораздо более явный, как регулярное выражение и strip_tags
использует один из синтаксических анализаторов XML, поставляемых с PHP, для удаления инструкций по обработке. Например расширение PHP DOM. Его можно обернуть в функцию, которую легко применить к строке:
dom_strip_pis($str)
Такая примерная функция также работает с имеющейся у вас строкой XML, которая использует зарезервированное имя. 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, как указано в последнем примере, не потребует от вас мелкого анализа.
Вы были очень близко - обратите внимание на '?' в самом конце перед закрывающей угловой скобкой:
<?xml:namespace prefix = o /?>
Чтобы соответствовать этому, вам понадобится следующее:
<?php
$clean=preg_replace('/<\?xml[^>]+\/\?>/im', '', $dirty);
?>