替换标签名称中的标点符号的最佳方法是什么


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不是解析htmlxml的正确方法,但我担心我在我的情况下使用preg_replace(),因为DOMDocument()无法读取我的 ~250K 行糟糕的结构化命名空间提供的 xml- 内容。提供的 xsd 文件(~25 个方案)已经过时(现在已经 6 年了),内容提供商不愿意解决这个问题。

我发现SimpleXMLElement()_替换:后可以工作.

您可以捕获 <> 之间的内容,然后将:替换为 _ ,如下所示:

$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>

如果您不使用属性,则此代码将为您工作:

$string = preg_replace_callback(
    '#</?['w:]+>#',
    function ($match) {
        list($tag) = $match;
        return str_replace(':', '_', $tag);
    },
    $string
);

如果您确实使用属性,请查看以下内容:如何使用 PHP 更改 XML 标记名称?

你的意思是以下几点:

$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);

链接:http://php.net/strtr。我刚刚发现这个,所以不知道这是否适合你。

您可以尝试遵循正则表达式,

<'/?'w+(:)'w+>

工作演示

可以使用组捕获将其替换为_