用正则表达式替换htmlentities的嵌套标签 - PHP

时间:2012-04-19 18:04:01

标签: php regex

这是xml代码,我将此文本加载为String,我需要将所有嵌套标记和内容替换为htmlentities ..

<?xml version="1.0" encoding="utf-8"?>
<data>
<target><x id="25e02e3e839c-a1e6b03cb682"  pid="NLSheets" name="NLSheets" />Sheets"</target>
<target>"<x id="3510a371bdf8-861b965564ea" pid="NLTable" name="NLTable" />Table"</target>
<target>"<x id="48a1560eaa68-c400c8394f0a"  pid="NLCaption" name="NLCaption" />Caption"</target>
</data>

我已经使用以下php代码完成任务。

function html_entities($matches) {
  return str_replace($matches[1], htmlentities($matches[1]), $matches[0]);
}

function get_tag( $tagname, $xml ) {
 $pattern = "/<$tagname ?.*>(.*?)<\/$tagname>/"; 
 $content = preg_replace_callback($pattern,  html_entities, $xml);
 return $content;
}

$content = get_tag('target', $str);

echo $content; 

现在的问题在于正则表达式。我使用了正则表达式

你可以在get_tag函数中看到

$pattern = "/<$tagname ?.*>(.*?)<\/$tagname>/";将在运行时构建为

/<target ?.*>(.*?)<\/target>

现在我无法解决问题...嵌套标签值未转换为htmlentities。

请帮忙

1 个答案:

答案 0 :(得分:1)

将行更改为:

$pattern = "/<$tagname ?.*?>(.*?)<\/$tagname>/"; 

你需要一个额外的非贪婪修饰符,以防止搜索开始标记的结束部分(>)走得太远并抓住你的内部内容(因此不能使它可用于括号分组因此,htmlentities。

我们可以通过在末尾使用's'修饰符来改善这一点,以允许内容中的换行符(因为点符号默认不包括换行符)以及防止/内允许换行符的开始标记,并允许任何类型的空格将元素名称与属性分开,并允许在结束标记的末尾添加空格:

$pattern = "/<$tagname(?:\s[^\/]*?)?>(.*?)<\/$tagname\s*>/s";

缩短它:

$pattern = "@<$tagname(?:\s[^/]*?)?>(.*?)</$tagname\s*>@s";

用于处理所有这些可能的边缘情况,使用XML解析器更安全。例如,这不会抓住:

<target><![CDATA[ </target> ]]></target>