有效 XML 标记名称的 PHP 正则表达式

Posted

技术标签:

【中文标题】有效 XML 标记名称的 PHP 正则表达式【英文标题】:PHP regex for valid XML tag name 【发布时间】:2011-11-21 16:05:09 【问题描述】:

什么是一个好的通用正则表达式(用 php 术语)来确定一个字符串是否是一个有效的 XML 标记名称?

我开始使用/[^>]+/i,但它也匹配4 \<< 之类的东西,这显然不是一个有效的标签名称。

所以我尝试组合所有有效字符,例如 /[a-z][a-z0-9_-]*/i,这也不完全正确,因为 XML 允许几乎任何外语标签名称中的字符。

我现在卡住了 - 我应该只检查是否有空格字符吗?还是有更多内容?

【问题讨论】:

【参考方案1】:

为什么不直接使用已经知道规则的 XML 解析器/生成器?

function isValidXmlElementName($elementName)

    try 
        new DOMElement($elementName);
     catch (DOMException $e) 
        return false;
    
    return true;


var_dump(isValidXmlElementName(' ')); // false 
var_dump(isValidXmlElementName('1')); // false
var_dump(isValidXmlElementName('-')); // false
var_dump(isValidXmlElementName('a')); // true

【讨论】:

【参考方案2】:

来自XML specification:

[4]     NameStartChar      ::=      ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
[4a]    NameChar       ::=      NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
[5]     Name       ::=      NameStartChar (NameChar)*

【讨论】:

看起来不错,但我如何在 PHP 正则表达式中调整它?解释器会理解#xC0-#xD6 之类的范围值吗?【参考方案3】:

来自相同的规范,但更清楚一点:

“鼓励文档作者使用自然语言中有意义的单词或单词组合的名称,并避免名称中的符号或空格字符。请注意,冒号、连字符-减号、句号(句点)、低线(下划线)和中间点是明确允许的。

ASCII 符号和标点符号以及相当多的 Unicode 符号字符被排除在名称之外,因为它们在 XML 名称用于 XML 文档之外的上下文中作为分隔符更有用;提供该组为这些上下文提供了关于哪些内容不能成为 XML 名称的硬性保证。字符#x037E(希腊问号)被排除在外,因为规范化后它变成了一个分号,这可能会改变实体引用的含义。”

据我所知,几乎所有事情都会发生。正如 Gordon 在下面所说,最好使用了解规则的解析器!

【讨论】:

以上是关于有效 XML 标记名称的 PHP 正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

PHP 正则表达式匹配 img ,PHP 正则提取或替换图片 img 标记中的任意属性。

C# 正则表达式:将空格替换为 XML 标记

如何检查字符串是不是是有效的 XML 元素名称?

用于删除 XML 标记及其内容的正则表达式

使用正则表达式关闭打开的 XML 标记

正则表达式在任何 xml 标记中添加属性