我希望你能翻译一个正则表达式,以验证所有可能的DN(区分名)类型。
我创建了一个正则表达式,但它并不是很好。
/([A-z0-9=]{1}[A-z0-9]{1})*[,??]/
和其他一些修改后,但都没有成功。
可能的DN可以是:
CN=abcd,CN=abcd,O=abcd,C=us
CN=abcd0520,CN=users,O=abcd,C=us
C=us
etc
我希望你能翻译一个正则表达式,以验证所有可能的DN(区分名)类型。
我创建了一个正则表达式,但它并不是很好。
/([A-z0-9=]{1}[A-z0-9]{1})*[,??]/
和其他一些修改后,但都没有成功。
可能的DN可以是:
CN=abcd,CN=abcd,O=abcd,C=us
CN=abcd0520,CN=users,O=abcd,C=us
C=us
etc
我最近有这方面的需求,所以我创建了一个完美遵循LDAPv3可分辨名称语法规则的工具,该规则在RFC-2253中定义。
属性类型可以通过两种方式表达。以字母开头的字母数字字符串,使用以下验证:
[A-Za-z][\w-]*
或者它可以是OID,使用以下验证:
\d+(?:\.\d+)*
因此,属性类型使用以下验证:
[A-Za-z][\w-]*|\d+(?:\.\d+)*
属性值可以通过三种方式表达。十六进制字符串,它是具有前导#
的十六进制对序列。 十六进制字符串使用以下验证:
#(?:[\dA-Fa-f]{2})+
或转义字符串;每个非特殊字符“按原样”表示(使用[^,=\+<>#;\\"]
进行验证)。 特殊字符可以以前导符\
表示(使用\\[,=\+<>#;\\"]
进行验证)。 最后,任何字符都可以以带前导符\
的十六进制对表示(使用\\[\dA-Fa-f]{2}
进行验证)。 转义字符串使用以下验证:
(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*
或引用字符串;该值以"
开头和结尾,并且可以包含任何未转义的字符,除了\
和"
。 此外,可以使用上面从转义字符串中的任何方法。 引用字符串使用以下验证:
"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*"
所有组合起来,属性值使用以下验证:
#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*"
BNF中的名称组件为:
name-component = attributeTypeAndValue *("+" attributeTypeAndValue)
attributeTypeAndValue = attributeType "=" attributeValue
在正则表达式中:
(?#attributeType)=(?#attributeValue)(?:\+(?#attributeType)=(?#attributeValue))*
将 (?#attributeType)
和 (?#attributeValue)
占位符替换为上面的值,得到以下结果:
(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*")(?:\+(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*"))*
这会验证单个名称部件。
最终,可分辨名称的 BNF 格式为:
name-component *("," name-component)
在正则表达式中:
(?#name-component)(?:,(?#name-component))*
将 (?#name-component) 占位符替换为上面的值,得到以下结果:
^(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*")(?:\+(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<<>gt;#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*"))*(?:,(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*")(?:\+(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*"))*)*$
\s*
,并在name-component内部等号的两侧添加了它。 - DuBistKomisch)=(
在四个位置变成了 )\s*=\s*(
,另外还有一个 ,(
变成了 ,\s*(
。 - DuBistKomisch这对我有用:
表达式:
^(?<RDN>(?<Key>(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+)\=(?<Value>(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+))(?:\s*\,\s*(?<RDN>(?<Key>(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+)\=(?<Value>(?:\\[0-9A-Fa-f]{2}|\\\[^=\,\\]|[^=\,\\]+)+)))*$
测试:
CN=Test User Delete\0ADEL:c1104f63-0389-4d25-8e03-822a5c3616bc,CN=Deleted Objects,DC=test,DC=domain,DC=local
该表达式已经进行了正则表达式转义,为了避免在C#中重复所有反斜杠,请确保在字符串前面加上未转义的字面量@符号,即
var dnExpression = @"...";
这将产生四个组,第一个是整个字符串的副本,第二个是最后一个RDN的副本,第三和第四个是键/值对。您可以使用每个组的Captures集合来索引每个键/值。
您还可以使用此方法通过将表达式裁剪到通常的“^... $”所包围的“(?...)”组来验证RDN以要求完整值(字符串的开始-结束)。
我允许十六进制特殊字符转义“\”,简单字符转义“\”或除“,\”之外的任何其他内容在键/值 DN文本中。我猜想通过花费额外的时间浏览MSDN AD标准并限制允许的字符以精确匹配允许或不允许的内容,可以完善此表达式。但我认为这是一个很好的开始。
我创建了一个。工作得很好。
^(\w+[=]{1}\w+)([,{1}]\w+[=]{1}\w+)*$
CN=Jeff Smith,OU=Sales,DC=Fabrikam,DC=COM
一起使用。 - Smitt\w+
对于匹配它们来说是非常不足的。@Smitt评论中的DN之所以不匹配正则表达式,仅仅是因为其中一个值包含了一个空格,这不仅是允许的,而且非常普遍。[^,]+
是朝着正确方向迈出的一步,但请记住,有几个保留字符,所有这些字符都可以用\进行转义。正则表达式必须考虑到这一点。 - Adi Inbar[,{1}]
看起来多余了。为什么需要为一个单字符创建括号集合?而且,在后面跟着的东西不匹配逗号,为什么还需要 {1}
?删除所有这些内容并使用 ,
替换即可,在正则表达式中没有实际变化。 - Adi Inbar