替换标签名称中标点符号的最佳方法是什么?
What is the best way to replace the punctuation in tag names?
我有理由将所有标签名称中的标点符号替换为下划线(请不要问我为什么它与问题无关)。
与问题相关的是我想:
<data:data>
<another:data>Content</another:data>
<another:data>Content</another:data>
<another:data>Content</another:data>
<another:data attribute="attr : content">This content should : not be affected</another:data>
<another:data><![CDATA[This content should : not be affected]]></another:data>
</data:data>
替换为:
<data_data>
<another_data>Content</another_data>
<another_data>Content</another_data>
<another_data attribute="attr : content">This content should : not be affected</another_data>
<another_data><![CDATA[This content should : not be affected]]></another_data>
</data_data>
但是使用 php
执行此操作的最佳方法是什么?
我知道 regex
不是解析 html
或 xml
的正确方法,但恐怕我很想在我的代码中使用 preg_replace()
情况是因为 DOMDocument()
无法读取我提供的 ~250K 行错误的结构化命名空间 xml- 内容。提供的 xsd 文件(~25 方案)已过时(6 年了),内容提供者不愿修复此问题。
我发现 SimpleXMLElement()
在将 :
替换为 _
后有效。
你的意思是:
$string = "<data:data>
<another:data>Content</another:data>
<another:data>Content</another:data>
<another:data>Content</another:data>
<another:data>Content</another:data>
</data:data>";
$string = str_replace(':', '_', $string);
或
$string = str_replace('another:data', 'another_data', $string);
更新
也许您可以尝试以下方法:
$replace = array('another:data' => 'another_data', '/another:data' => '/another_data'); // So you can easily add more strings to replace
strtr($string, $replace);
link:http://php.net/strtr。我刚找到这个,所以不知道这是否适合你。
如果您不使用属性,此代码适用于您:
$string = preg_replace_callback(
'#</?[\w:]+>#',
function ($match) {
list($tag) = $match;
return str_replace(':', '_', $tag);
},
$string
);
如果您使用属性,请查看:How do I change XML tag names with PHP?
您可以尝试使用正则表达式,
<\/?\w+(:)\w+>
可以用Group抓取替换成_
您可以捕获 <
和 >
之间的内容,然后将 :
替换为 _
,如下所示:
$string = "<data:data>
<another:data:data>Content:</another:data>
<another:data>:Content</another:data>
<another:data>Content</another:data>
<another:data><![CDATA[This content should : not be affected]]>Content</another:data>
</data:data>";
$regex = '~<[^!][^>]*>~';
$replaced = preg_replace_callback(
$regex,
function($m) { return str_replace(':', '_', $m[0]);},
$string);
echo $replaced;
输出:
<data_data>
<another_data_data>Content:</another_data>
<another_data>:Content</another_data>
<another_data>Content</another_data>
<another_data><![CDATA[This content should : not be affected]]>Content</another_data>
</data_data>
我有理由将所有标签名称中的标点符号替换为下划线(请不要问我为什么它与问题无关)。
与问题相关的是我想:
<data:data>
<another:data>Content</another:data>
<another:data>Content</another:data>
<another:data>Content</another:data>
<another:data attribute="attr : content">This content should : not be affected</another:data>
<another:data><![CDATA[This content should : not be affected]]></another:data>
</data:data>
替换为:
<data_data>
<another_data>Content</another_data>
<another_data>Content</another_data>
<another_data attribute="attr : content">This content should : not be affected</another_data>
<another_data><![CDATA[This content should : not be affected]]></another_data>
</data_data>
但是使用 php
执行此操作的最佳方法是什么?
我知道 regex
不是解析 html
或 xml
的正确方法,但恐怕我很想在我的代码中使用 preg_replace()
情况是因为 DOMDocument()
无法读取我提供的 ~250K 行错误的结构化命名空间 xml- 内容。提供的 xsd 文件(~25 方案)已过时(6 年了),内容提供者不愿修复此问题。
我发现 SimpleXMLElement()
在将 :
替换为 _
后有效。
你的意思是:
$string = "<data:data>
<another:data>Content</another:data>
<another:data>Content</another:data>
<another:data>Content</another:data>
<another:data>Content</another:data>
</data:data>";
$string = str_replace(':', '_', $string);
或
$string = str_replace('another:data', 'another_data', $string);
更新
也许您可以尝试以下方法:
$replace = array('another:data' => 'another_data', '/another:data' => '/another_data'); // So you can easily add more strings to replace
strtr($string, $replace);
link:http://php.net/strtr。我刚找到这个,所以不知道这是否适合你。
如果您不使用属性,此代码适用于您:
$string = preg_replace_callback(
'#</?[\w:]+>#',
function ($match) {
list($tag) = $match;
return str_replace(':', '_', $tag);
},
$string
);
如果您使用属性,请查看:How do I change XML tag names with PHP?
您可以尝试使用正则表达式,
<\/?\w+(:)\w+>
可以用Group抓取替换成_
您可以捕获 <
和 >
之间的内容,然后将 :
替换为 _
,如下所示:
$string = "<data:data>
<another:data:data>Content:</another:data>
<another:data>:Content</another:data>
<another:data>Content</another:data>
<another:data><![CDATA[This content should : not be affected]]>Content</another:data>
</data:data>";
$regex = '~<[^!][^>]*>~';
$replaced = preg_replace_callback(
$regex,
function($m) { return str_replace(':', '_', $m[0]);},
$string);
echo $replaced;
输出:
<data_data>
<another_data_data>Content:</another_data>
<another_data>:Content</another_data>
<another_data>Content</another_data>
<another_data><![CDATA[This content should : not be affected]]>Content</another_data>
</data_data>