如何逃避角色c#拒绝逃脱?

时间:2016-06-02 20:58:26

标签: c# regex

更新

在我看到之前“只需使用字符串文字!”请注意我正试图逃避角色()-_=+{[}|]。我认为正则表达式引擎不知道如何正确解析我的表达式。有一点我|]转换为]|并发现我的正则表达式只要它有一个低位,高位和数字就会传递所有内容。现在它失败了一切。我正在寻找的答案将解释我的正则表达式的错误。

我有这个正则表达式,我用于密码

^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[~`!@#$%^&*()-_=+{[}|]:\";'<>?,./\\])[^\r\n\t\f ]{8,16}$

这是javascript等价文字:

/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[~`!@#$%^&*()\-_=+{[}\]|:";'<>?,.\/\\])[^\r\n\t\f ]{8,16}$/

javascript表达式运行正常。至少1个小写,1个大写,1个数字,1个特殊字符,并且它在8到16个字符之间。

我的问题是我无法弄清楚我是怎么想逃避小组中的分组角色

(?=.*[~`!@#$%^&*()-_=+{[}|]:\";'<>?,./\\])

具体而言,{[}|]部分。如果我尝试\[它会给出错误,但是好的MSDN却说错了。

我在密码字段的验证属性中使用它

[RegularExpression("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[~`!@#$%^&*()-_=+{[}|]:\";'<>?,./\\])[^\r\n\t\f ]{8,16}$", ErrorMessage = "Password must meet all specified criteria.")]

1 个答案:

答案 0 :(得分:4)

  

我正在寻找的答案将解释我的正则表达式的错误

这是你的正则表达式:

[RegularExpression(
  "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[~`!@#$%^&*()-_=+{[}|]:\";'<>?,./\\])[^\r\n\t\f ]{8,16}$"

这是错误的。你想知道它为什么是错的。让我们分解吧。

首先,这是一个C#字符串文字。 它实际代表什么字符?请记住,C#字符串文字包含转义序列。这件事中的字符是:

^ ( ? = . * [ a - z ] ) ( ? = . * [ A - Z ] ) ( ? = . * 
\    -- this is the character represented by \\
d ) ( ? = . * [ ~ ` ! @ # $ % ^ & * ( ) - _ = + { [ } | ] :
"    -- this is the character represented by \"
; ' < > ? , . / 
\  -- this is the character represented by \\
] ) [ ^ 
<carriage return>   -- represented by \r
<newline>           -- represented by \n
<tabstop>           -- represented by \t
<feed>              -- represented by \f
<space>
] { 8 , 1 6 } $ 

这些是字符串中的字符。 他们代表你想要的正则表达式吗?显然不是。该字符串包含正则表达式(为了清楚起见,我将在子表达式之间添加换行符):

^(?=.*[a-z])  -- right
 (?=.*[A-Z])  -- right
 (?=.*\d)     -- right
 (?=.*[~`!@#$%^&*()-_=+{[}|]:";'<>?,./\]) -- NOPE
 [^<carriage return><newline><tabstop><feed><space>] -- seems dodgy
 {8,16}$ -- right

标记为NOPE的位显然是错误的。你想要它是什么字符串?你希望它是这组字符:

 (?=.*[~`!@#$%^&*()\-_=+{[}\]|:";'<>?,./\\])

但它不是那组字符。现在你明白你做错了吗?

在C#常规字符串文字中,该字符集由以下表示:

 "(?=.*[~`!@#$%^&*()\\-_=+{[}\\]|:\";'<>?,./\\\\])"

在C#逐字字符串文字中,该字符集由:

表示
 @"(?=.*[~`!@#$%^&*()\-_=+{[}\]|:"";'<>?,./\\])"

请注意,除了双引号外,逐字逐句是逐字的。由此得名。 在C#中构建正则表达式时使用逐字文字。

此外,将来你应该通过尝试自己解决小的子问题来解决这类问题。如果你尝试编写一个与单[匹配的正则表达式,那么你会很快发现你的问题;如果你无法这样做,那么关于如何这样做的问题将会更容易回答。正则表达式是组合的;将问题分解为更小的问题,测试每个解决方案,然后组合它们。如果你继续这样做:

const string Lowercase = "(?=.*[a-z])";
const string Uppercase = "(?=.*[A-Z])";
const string Digits = "(?=.*\\d)";
const string Symbols = "(?=.*[~`!@#$%^&*()-_=+{[}|]:\";'<>?,./\\])"; // Wrong!
const string NoWhitespace = "[^\r\n\t\f ]"; // Dodgy!
const string Password = "^" + Lowercase + Uppercase + Digits + Symbols + NoWhitespace + "{8,16}$";

那么您将拥有现成的单元测试代码。当密码regexp失败时,您可以独立测试它的每个部分,并找出出错的地方,您可以尝试将“符号”替换为匹配[(的表达式,比如说,并调试它。 (还要注意我的版本有多自我记录,可维护和清晰。它看起来仍然像调制解调器线路噪声,但至少它是不言自明的调制解调器线路噪声。)