正则表达式,用于将字符串重新格式化为安全的xml标记

时间:2009-11-30 16:09:40

标签: xml regex

我目前正在尝试编写RegexReplace以确保输入可以用作有效的XML标记,这意味着:没有空格,没有特殊字符,只有小写等...

是否有一个共同的方法,或者我必须从头开始做什么?

示例:

string Invalid = "asd(%4 asKUd n!%mn &§a_As1";  // Invalid as a tag

string Valid = FormatToSafeXmlTag(Invalid);  // How to write this function?

// Valid = "asd4_askud_nmna_as1"

3 个答案:

答案 0 :(得分:6)

根据XML specification,元素的名称以下列方式形成:

Name   ::=  NameStartChar (NameChar)*

哪里

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]

转换为正则表达式很简单。

如果您要删除此定义之外的任何字符,只需反转表达式所需的字符。

答案 1 :(得分:2)

  • 仅限小写:^[a-z]+$
  • 第一个char小写,(可选)剩余字符lowecase / numbers ^[a-z][a-z0-9]*$
  • 仅限大写:^[A-Z]+$
  • 第一个字母字母,(可选)剩余字符字母数字^[a-zA-Z][a-zA-Z0-9]*$

编辑:在javascript中删除除小写字符以外的所有内容:

str = str.replace(/[^a-z]/g, "");

捕获是当用户只输入不可接受的字符时 - 您将最终尝试创建一个空字符串的xml标记。我宁愿让用户再试一次 - 输入小写字符串有多难?

注意:另一个边缘情况是用户输入xml或其中任何不区分大小写的变体(感谢@Tim的回答)。如果您使用的是javascript,则无法使用Tim建议的解决方案,因为它使用了lookbehind,这是javascript正则表达式不支持的功能。

JavaScript代码:

str = str.replace(/\s/g, "_"); //replaces spaces

str = str.replace(/[^a-zA-Z0-9_\-]/g, "");//trim symbols

var reg = new RegExp(/^xml/i); 

if(str.length == 0 || reg.test(str)) //is it empty or "xml" or "XmL" or ..
    alert("invalid regex");

答案 2 :(得分:2)

XML标记(我假设您询问标记名称)必须遵循以下规则:

  • 以字母,点,冒号或下划线开头
  • 仅包含字母,数字,点,下划线或冒号(用于命名空间)
  • 不得以xml
  • 开头

因此,有效标记名称的正则表达式可以是:

^(?!xml)[\w.:][\w\d.:]*$

取决于您的正则表达式风格(例如,.NET包含\w中的Unicode字母,这对于标记名称是合法的)。你也可以使用

^(?!xml)[p\{L}._:][\p{L}\p{N}._:]*$

如果\w不包含Unicode字母。

但是,当然您可以使用更严格的规则,并且可能并非所有XML解析器都可以处理完整的Unicode标记名称。所以最后,

^(?!xml)[A-Za-z._:][A-Za-z0-9._:]*$

可能是你最好的选择......