什么是有效的xml名称的正则表达式?

时间:2010-07-01 13:34:10

标签: xml

[a-zA-Z_:]([a-zA-Z0-9_:.])*

这会吗?

6 个答案:

答案 0 :(得分:10)

您的意思是XML 元素名称吗?如果是这样,不,那太独了,有很多有效的字符,不包括在内。规范herehere中的更多内容:

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] 

NameChar         ::=    NameStartChar | "-" | "." | [0-9] | #xB7 |
                        [#x0300-#x036F] | [#x203F-#x2040] 

Name             ::=    NameStartChar (NameChar)* 

答案 1 :(得分:5)

编辑:

.NET还有方法XmlConvert.VerifyName(string)

来自Wikipedia

以下代码点范围中的Unicode字符在XML 1.0文档中有效:

  • U + 0009
  • U + 000A
  • U + 000D
  • U + 0020-U + D7FF
  • U + E000-U + FFFD
  • U + 10000-U + 10FFFF

以下代码点范围中的Unicode字符在XML 1.1文档中始终有效:

  • U + 0001-U + 0008
  • U + 000B-U + 000C
  • U + 000E-U + 001F
  • U + 007F-U + 0084
  • U + 0086-U + 009F

前面的代码点包含在以下代码点范围内,这些代码点范围仅在XML 1.1文档的某些上下文中有效:

  • U + 0001-U + D7FF
  • U + E000-U + FFFD
  • U + 10000-U + 10FFFF

答案 2 :(得分:3)

^(:|[A-Z]||[a-z]|[\xC0-\xD6]|[\xD8-\xF6]|[\xF8-\u02FF]|[\u0370-\u037D]|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u2070-\u218F]|[\u2C00-\u2FEF]|[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD])(:|[A-Z]||[a-z]|[\xC0-\xD6]|[\xD8-\xF6]|[\xF8-\u02FF]|[\u0370-\u037D]|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u2070-\u218F]|[\u2C00-\u2FEF]|[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD]|-|.|[0-9]|\xB7|[\u0300-\u036F]|[\u203F-\u2040])*$

This would match correctly all but [#xFDF0-#xFFFD]|[#x10000-#xEFFFF] as it is not possible (as far as I know) to match ASCII characters outside 16bit in regex.

To correct xml names you can use this function:

<?php
        private static function getValidXMLName($value){

    $validStartNameChar =
        '[A-Z]|_|[a-z]|[\xC0-\xD6]|[\xD8-\xF6]|[\xF8-\x{2FF}]|[\x{370}-\x{37D}]|[\x{37F}-\x{1FFF}]|'.
        '[\x{200C}-\x{200D}]|[\x{2070}-\x{218F}]|[\x{2C00}-\x{2FEF}]|[\x{3001}-\x{D7FF}]|[\x{F900}-\x{FDCF}]|[\x{FDF0}-\x{FFFD}]';
    $validNameChar = $validStartNameChar . '|\-|\.|[0-9]|\xB7|[\x{300}-\x{36F}]|[\x{203F}-\x{2040}]';
    $valueClean = preg_replace('/(?!'.$validNameChar.')./u','',$value);
    $firstChar = mb_substr($valueClean,0,1);
    if (!(strlen(preg_replace('/(?!'.$validStartNameChar.')./u','',$firstChar))>0)){
        $return = '_' . "$valueClean";
    } else {
        $return = "$valueClean";
    }
    return $return;
}

This will replace any incorrect characters with nothing and if the first character after this is not a valid first character will prepend an underscore

Its not maybe the prettiest or best way but for what I am using it for (building an XML log) it will be fine

答案 3 :(得分:2)

背景资料:

根据w3schools.com,XML中标记名称的规则是

  1. 元素名称区分大小写
  2. 元素名称必须以字母或下划线开头
  3. 元素名称不能以字母xml(或XML,或Xml等)
  4. 开头
  5. 元素名称可以包含字母,数字,连字符,下划线和句点
  6. 元素名称不能包含空格

  7. 可能的解决方案:

    让我们使用javascript在几个步骤中完成。如有必要,请随时翻译。为什么一个复杂的正则表达式,当你可以通过多个正则表达式测试将其分解为更易读和可维护的代码?

    function isXMLTagName ( tag ) // returns true if meets cond. 1-5 above
    {
        var t = !/^[xX][mM][lL].*/.test(tag); // condition 3 
        t = t && /^[a-zA-Z_].*/.test(tag);  // condition 2
        t = t && /^[a-zA-Z0-9_\-\.]+$/.test(tag); // condition 4
        return t; 
    }
    

    我现在在项目中遇到同样的问题。希望这有效。

答案 4 :(得分:0)

对于Node 10和最新的Chrome

/[\p{L}_][\p{L}.\d_-]/u

答案 5 :(得分:0)

给出以下基本标准:

  • 允许的字符是标准的26个拉丁字母,10个阿拉伯数字和下划线,
  • 主角只能是有效字母或下划线,
  • 在任何情况下,名称都不能以“ xml”开头

我将以下正则表达式模式用于基本XML元素(标签)名称验证:

/^([_a-z][\w]?|[a-w_yz][\w]{2,}|[_a-z][a-l_n-z\d][\w]+|[_a-z][\w][a-k_m-z\d][\w]*)$/i

...与上面的单字符串示例相比,这很短,而且我发现在概述的限制范围内效果很好。另外,快速浏览上面的许多较长的示例,我看不到它们在任何情况下都捕获以“ xml”开头的元素(标签)名称的位置。

故障:

  • 第一个块将验证任何长度为1或2个字符的字符串。
  • 第二个块将验证任何以“ x”(或“ X”)开头的3个以上的字符串。
  • 第三个块将验证在第二个位置没有“ m”(或“ M”)的任何3+字符串。
  • 第四个块将验证在第3个位置上没有“ l”(或“ L”)的任何3+字符串。
  • / i设置不区分大小写的标志,以显着减少块内所需的字符文字数量。

我发表此文章的想法是,它可以帮助正在寻找一种更简单(尽管以英语为中心)的解决方案来解析一组简化的XML元素(标签)名称的人。