代码之家  ›  专栏  ›  技术社区  ›  Matt M

是否有更简洁的正则表达式来完成此任务?

  •  5
  • Matt M  · 技术社区  · 15 年前

    首先,我为这个蹩脚的头衔感到抱歉,但我想不出一个更好的。我需要测试密码以确保:

    密码必须至少包含以下三项:

    • 大写字母
    • 小写字母
    • 数字
    • 特殊字符

    以下是我的想法(它是可行的,但我想知道是否有更好的方法可以做到这一点):

        Dim lowerCase As New Regex("[a-z]")
        Dim upperCase As New Regex("[A-Z]")
        Dim numbers As New Regex("\d")
        Dim special As New Regex("[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#]")
    
        Dim count As Int16 = 0
    
        If Not lowerCase.IsMatch(txtUpdatepass.Text) Then
            count += 1
        End If
        If Not upperCase.IsMatch(txtUpdatepass.Text) Then
            count += 1
        End If
        If Not numbers.IsMatch(txtUpdatepass.Text) Then
            count += 1
        End If
        If Not special.IsMatch(txtUpdatepass.Text) Then
            count += 1
        End If
    

    如果至少有3个标准没有被满足,我会处理它。我不太熟悉正则表达式,并且一直在网上阅读大量教程。有没有办法把所有4个正则表达式组合成一个?但我想这样做不允许我检查是否至少满足3个标准。

    另一个注意事项是,是否有一个站点具有所有需要在regex中转义的字符的详尽列表(那些具有特殊含义的字符-例如,$、^,等等)?

    一如既往,蒂娅。我无法充分表达我认为这个网站有多棒。

    6 回复  |  直到 15 年前
        1
  •  6
  •   eykanal    15 年前

    你拥有它的方式是尽可能好的。你可以在一行中完成这一切,但这将是非常模糊的,并不会真正有帮助。

    想想你想做什么;你想检查四个不同的标准。因为每个标准本质上都是一个比较,所以您需要分别检查每个标准,这就是您要做的。

        2
  •  3
  •   adamnfish    15 年前

    我认为你的方法是明智的。很清楚你想要达到的目标是什么(以一种正确的正则表达式不会达到的方式),而且它是有效的!

    大多数语言都有非常好的关于regex处理的文档,所以我建议先看一下。否则,我会发现 JavaScript MDC regex documentationt 非常适合该语言支持的正则表达式的子集(包括最实际的用法)。

    不过,还有一个提示——当您位于字符集(方括号)内时,不需要转义所有这些特殊字符。”[{}[]?*^$是完全有效的。(显然您需要转义)和分隔符(“)。

        3
  •  2
  •   Lieven Keersmaekers    15 年前

    我相信这是可行的,但它只是表明它会变得多么丑陋。你不会得到任何速度或可读性。

    Try
        If Regex.IsMatch(SubjectString, "(?=\S*?[a-z])(?=\S*?[0-9])(?=\S*?[\\.+*?\^$[\]()|{}/'#])\S{3,}|(?=\S*?[A-Z])(?=\S*?[0-9])(?=\S*?[\\.+*?\^$[\]()|{}/'#])\S{3,}|(?=\S*?[A-Z])(?=\S*?[a-z])(?=\S*?[\\.+*?\^$[\]()|{}/'#])\S{3,}|(?=\S*?[A-Z])(?=\S*?[a-z])(?=\S*?[0-9])\S{3,}") Then
            ' Successful match
        Else
            ' Match attempt failed
        End If
    Catch ex As ArgumentException
        'Syntax error in the regular expression
    End Try
    

    RegexBuddy解释

    ' (?=\S*?[a-z])(?=\S*?[0-9])(?=\S*?[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#])\S{3,}|(?=\S*?[A-Z])(?=\S*?[0-9])(?=\S*?[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#])\S{3,}|(?=\S*?[A-Z])(?=\S*?[a-z])(?=\S*?[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#])\S{3,}|(?=\S*?[A-Z])(?=\S*?[a-z])(?=\S*?[0-9])\S{3,}
    ' 
    ' Match either the regular expression below (attempting the next alternative only if this one fails) «(?=\S*?[a-z])(?=\S*?[0-9])(?=\S*?[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#])\S{3,}»
    '    Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\S*?[a-z])»
    '       Match a single character that is a “non-whitespace character” «\S*?»
    '          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    '       Match a single character in the range between “a” and “z” «[a-z]»
    '    Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\S*?[0-9])»
    '       Match a single character that is a “non-whitespace character” «\S*?»
    '          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    '       Match a single character in the range between “0” and “9” «[0-9]»
    '    Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\S*?[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#])»
    '       Match a single character that is a “non-whitespace character” «\S*?»
    '          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    '       Match a single character present in the list below «[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#]»
    '          A \ character «\\»
    '          A . character «\.»
    '          A + character «\+»
    '          A * character «\*»
    '          A ? character «\?»
    '          A ^ character «\^»
    '          A $ character «\$»
    '          A [ character «\[»
    '          A ] character «\]»
    '          A ( character «\(»
    '          A ) character «\)»
    '          A | character «\|»
    '          A { character «\{»
    '          A } character «\}»
    '          A / character «\/»
    '          A ' character «\'»
    '          A # character «\#»
    '    Match a single character that is a “non-whitespace character” «\S{3,}»
    '       Between 3 and unlimited times, as many times as possible, giving back as needed (greedy) «{3,}»
    ' Or match regular expression number 2 below (attempting the next alternative only if this one fails) «(?=\S*?[A-Z])(?=\S*?[0-9])(?=\S*?[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#])\S{3,}»
    '    Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\S*?[A-Z])»
    '       Match a single character that is a “non-whitespace character” «\S*?»
    '          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    '       Match a single character in the range between “A” and “Z” «[A-Z]»
    '    Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\S*?[0-9])»
    '       Match a single character that is a “non-whitespace character” «\S*?»
    '          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    '       Match a single character in the range between “0” and “9” «[0-9]»
    '    Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\S*?[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#])»
    '       Match a single character that is a “non-whitespace character” «\S*?»
    '          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    '       Match a single character present in the list below «[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#]»
    '          A \ character «\\»
    '          A . character «\.»
    '          A + character «\+»
    '          A * character «\*»
    '          A ? character «\?»
    '          A ^ character «\^»
    '          A $ character «\$»
    '          A [ character «\[»
    '          A ] character «\]»
    '          A ( character «\(»
    '          A ) character «\)»
    '          A | character «\|»
    '          A { character «\{»
    '          A } character «\}»
    '          A / character «\/»
    '          A ' character «\'»
    '          A # character «\#»
    '    Match a single character that is a “non-whitespace character” «\S{3,}»
    '       Between 3 and unlimited times, as many times as possible, giving back as needed (greedy) «{3,}»
    ' Or match regular expression number 3 below (attempting the next alternative only if this one fails) «(?=\S*?[A-Z])(?=\S*?[a-z])(?=\S*?[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#])\S{3,}»
    '    Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\S*?[A-Z])»
    '       Match a single character that is a “non-whitespace character” «\S*?»
    '          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    '       Match a single character in the range between “A” and “Z” «[A-Z]»
    '    Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\S*?[a-z])»
    '       Match a single character that is a “non-whitespace character” «\S*?»
    '          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    '       Match a single character in the range between “a” and “z” «[a-z]»
    '    Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\S*?[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#])»
    '       Match a single character that is a “non-whitespace character” «\S*?»
    '          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    '       Match a single character present in the list below «[\\\.\+\*\?\^\$\[\]\(\)\|\{\}\/\'\#]»
    '          A \ character «\\»
    '          A . character «\.»
    '          A + character «\+»
    '          A * character «\*»
    '          A ? character «\?»
    '          A ^ character «\^»
    '          A $ character «\$»
    '          A [ character «\[»
    '          A ] character «\]»
    '          A ( character «\(»
    '          A ) character «\)»
    '          A | character «\|»
    '          A { character «\{»
    '          A } character «\}»
    '          A / character «\/»
    '          A ' character «\'»
    '          A # character «\#»
    '    Match a single character that is a “non-whitespace character” «\S{3,}»
    '       Between 3 and unlimited times, as many times as possible, giving back as needed (greedy) «{3,}»
    ' Or match regular expression number 4 below (the entire match attempt fails if this one fails to match) «(?=\S*?[A-Z])(?=\S*?[a-z])(?=\S*?[0-9])\S{3,}»
    '    Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\S*?[A-Z])»
    '       Match a single character that is a “non-whitespace character” «\S*?»
    '          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    '       Match a single character in the range between “A” and “Z” «[A-Z]»
    '    Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\S*?[a-z])»
    '       Match a single character that is a “non-whitespace character” «\S*?»
    '          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    '       Match a single character in the range between “a” and “z” «[a-z]»
    '    Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=\S*?[0-9])»
    '       Match a single character that is a “non-whitespace character” «\S*?»
    '          Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
    '       Match a single character in the range between “0” and “9” «[0-9]»
    '    Match a single character that is a “non-whitespace character” «\S{3,}»
    '       Between 3 and unlimited times, as many times as possible, giving back as needed (greedy) «{3,}»
    
        4
  •  1
  •   Bart Kiers    15 年前

    有没有办法把所有4个正则表达式组合成一个?但我想这样做不允许我检查是否至少满足3个标准。

    这就是麻烦的部分:“4取3”,很难翻译成(单个)regex。依我看,你现在的处理方式很好。

    另一方面,是否有一个站点有一个包含所有需要在regex中转义的字符的详尽列表(那些具有特殊含义的字符-例如,$,^,等等)?

    regex的特殊字符在实现和实现之间可能略有不同。但是,这些通常都是特殊的,因此需要避免:

    .    // match any character (often not line breaks)
    \    // used to escape characters
    *    // quantifier: zero or more
    +    // quantifier: one or more
    ?    // quantifier: once or none
    (    // start of a group
    )    // end of a group
    [    // start of a character class
    {    // start of a quantifier like X{2,5} (match 'X' between 2 and 5 times)
    ^    // start of the input string (or line)
    $    // end of the input string (or line)
    |    // OR
    

    注意,在一个字符类中,上面的大多数字符都失去了它们的“特殊能力”。字符类可以看作是regex语言中的一种小语言。它有自己的特色:

    ^    // when placed at the very start of the character class, it negates the class
    -    // when NOT placed at the start or end of the class, it denotes a range: [a-c] matches 'a', 'b' or 'c'
    \    // used to escape characters
    ]    // end of a character class
    


    一些例子:

    当你想匹配文字 ^ 在字符类中,您要么需要从一开始就对其进行转义,要么不将其放在开始处:

    [\^a]    // matches either 'a' or '^'
    [a^]     // matches either '^' or 'a'
    

    更多特殊字符类字符:

    [a[\]b]    // matches either 'a', '[', ']' or 'b'
    

    范围 - 作用中的角色:

    [a-c]     // matches 'a', 'b' or 'c'
    [ac-]     // matches 'a', 'c' or '-'
    [-ac]     // matches '-', 'a' or 'c'
    [a\-c]    // matches 'a', '-' or 'c'
    

    所以这些不需要逃避:

    [.()]    // simply matches either '.', '(' or ')'
    
        5
  •  0
  •   Jeff LaFay    15 年前

    对于要匹配每个条件的regex模式,您可能希望使每个条件保持独立,这样,每当某个条件与四个不同的模式之一匹配时,就可以迭代字符串并增加count dim。

    对于特殊字符,您至少可以清除该字符使其可读。

    \p{IsSpecials}
    

    这是我对模式所做的唯一更改,当然,您可以将大小写匹配与一个regex结合起来,但这是没有意义的,因为它们是不同的验证标准。

    要组合大小写集,可以执行此操作

    [a-zA-Z]
    
        6
  •  0
  •   Alan Moore Chris Ballance    15 年前

    为了好玩,这里有一个在一个regex中完成工作的好方法:

    "^(?=(?:.*[a-z]())?)(?=.*[A-Z]()|\1)(?=.*[0-9]()|\1\2)(?=\1\2\3|.*[.+*?^$\[\]()|{}/'#\\])[a-zA-Z0-9.+*?^$\[\]()|{}/'#\\]+$"
    

    这使用了一个由扬·高维茨和史蒂文·莱维汉在他们不可或缺的书中广受欢迎的技巧, Regular Expressions Cookbook :将空捕获组用作可选条件的复选框。

    首先,我们寻找一个小写字母,如果我们找到一个,设置组1。

    (?=(?:.*[a-z]())?)

    如果有大写字母,我们设置第2组。如果没有,并且未设置组1,则失败。这里的顺序很重要:检查第一个选项中的当前条件,然后执行返回断言。

    (?=.*[A-Z]()|\1)

    如果有数字,我们设置组3;如果没有,组1和组2没有设置,失败。

    (?=.*[0-9]()|\1\2)

    最后,如果第1组、第2组和第3组未设置,我们将寻找其中一个特色菜。这次我们可以先做后面的断言;如果已经满足了三个条件,我们就不关心第四个。

    (?=\1\2\3|.*[.+*?^$\[\]()|{}/'#\\])