此正则表达式中的前瞻说明

时间:2009-08-06 20:17:50

标签: regex

我理解正则表达式相当不错,但我不能经常使用它们来成为专家。我遇到了一个用于验证密码强度的正则表达式,但它包含了一些我不熟悉的正则表达式概念。正则表达式是:

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$

并且用简单的英语表示该字符串必须包含至少一个小写字符,一个大写字符和一个数字,并且该字符串必须至少为六个字符长。任何人都可以为我解释这个模式实际上如何描述这个规则吗?我看到一个字符串char ^的开头和字符串char $的结尾,三个带有lookaheads的组,一个匹配任何字符。并重复{6,}。

感谢任何可以帮助我理解这一点的正则表达大师。

5 个答案:

答案 0 :(得分:14)

在正常情况下,一段正则表达式匹配输入字符串的一部分,并“消耗”该字符串的那一部分。表达式的下一部分与下一部分字符串匹配,依此类推。

Lookahead断言消耗任何字符串,所以你的三个先行断言:

  • (?=.*\d)
  • (?=.*[a-z])
  • (?=.*[A-Z])

每个意思是“这个模式(分别跟一个数字,一个小写字母,一个大写字母的任何东西)必须出现在字符串中的某个地方”,但它们不会向前移动当前的匹配位置,所以剩下的表达式:

  • .{6,}

(表示“六个或更多字符”)必须仍然匹配整个输入字符串。

答案 1 :(得分:5)

前瞻组不消耗输入。这样,不同的前瞻组实际上匹配了相同的字符。

你可以这样想:搜索任何东西(.*),直到找到一个数字(\d)。如果你这样做,那就回到这个小组的开头(lookahead的概念)。现在查找任何内容(.*),直到找到小写字母。重复大写字母。现在,匹配任何6个或更多字符。

答案 2 :(得分:4)

彻底打破它。

^ -- Match beginning of line
(?=.*\d) -- The following string contains a number
(?=.*[a-z]) -- The following string contains a lowercase letter
(?=.*[A-Z]) -- The following string contains an uppercase letter
.{6,} -- Match at least 6, as many as desired of any character
$ -- Match end of line

答案 3 :(得分:1)

我去检查了如果使用Perl:

,这将是如何匹配的
perl -Mre=debug -E'q[  abc  345 DEF  ]=~/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$/'

Compiling REx "^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$"
synthetic stclass "ANYOF[\0-\11\13-\377{unicode_all}]".
Final program:
   1: BOL (2)
   2: IFMATCH[0] (9)
   4:   STAR (6)
   5:     REG_ANY (0)
   6:   DIGIT (7)
   7:   SUCCEED (0)
   8: TAIL (9)
   9: IFMATCH[0] (26)
  11:   STAR (13)
  12:     REG_ANY (0)
  13:   ANYOF[a-z] (24)
  24:   SUCCEED (0)
  25: TAIL (26)
  26: IFMATCH[0] (43)
  28:   STAR (30)
  29:     REG_ANY (0)
  30:   ANYOF[A-Z] (41)
  41:   SUCCEED (0)
  42: TAIL (43)
  43: CURLY {6,32767} (46)
  45:   REG_ANY (0)
  46: EOL (47)
  47: END (0)

floating ""$ at 6..2147483647 (checking floating) stclass ANYOF[\0-\11\13-\377{unicode_all}] anchored(BOL) minlen 6 
Guessing start of match in sv for REx "^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$" against "  abc  345 DEF  "
Found floating substr ""$ at offset 16...
start_shift: 6 check_at: 16 s: 0 endpos: 11
Does not contradict STCLASS...
Guessed: match at offset 0
Matching REx "^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$" against "  abc  345 DEF  "
   0 <> <  abc  345>         |  1:BOL(2)
   0 <> <  abc  345>         |  2:IFMATCH[0](9)
   0 <> <  abc  345>         |  4:  STAR(6)
                                    REG_ANY can match 16 times out of 2147483647...
  16 <c  345 DEF  > <>       |  6:    DIGIT(7) # failed...
  15 <c  345 DEF > < >       |  6:    DIGIT(7) # failed...
  14 <c  345 DEF> <  >       |  6:    DIGIT(7) # failed...
  13 <c  345 DE> <F  >       |  6:    DIGIT(7) # failed...
  12 <c  345 D> <EF  >       |  6:    DIGIT(7) # failed...
  11 <c  345 > <DEF  >       |  6:    DIGIT(7) # failed...
  10 <c  345> < DEF  >       |  6:    DIGIT(7) # failed...
   9 <c  34> <5 DEF  >       |  6:    DIGIT(7)
  10 <c  345> < DEF  >       |  7:    SUCCEED(0)
                                      subpattern success...
   0 <> <  abc  345>         |  9:IFMATCH[0](26)
   0 <> <  abc  345>         | 11:  STAR(13)
                                    REG_ANY can match 16 times out of 2147483647...
  16 <c  345 DEF  > <>       | 13:    ANYOF[a-z](24) # failed...
  15 <c  345 DEF > < >       | 13:    ANYOF[a-z](24) # failed...
  14 <c  345 DEF> <  >       | 13:    ANYOF[a-z](24) # failed...
  13 <c  345 DE> <F  >       | 13:    ANYOF[a-z](24) # failed...
  12 <c  345 D> <EF  >       | 13:    ANYOF[a-z](24) # failed...
  11 <c  345 > <DEF  >       | 13:    ANYOF[a-z](24) # failed...
  10 <c  345> < DEF  >       | 13:    ANYOF[a-z](24) # failed...
   9 <c  34> <5 DEF  >       | 13:    ANYOF[a-z](24) # failed...
   8 <bc  3> <45 DEF  >      | 13:    ANYOF[a-z](24) # failed...
   7 <abc  > <345 DEF  >     | 13:    ANYOF[a-z](24) # failed...
   6 < abc > < 345 DEF  >    | 13:    ANYOF[a-z](24) # failed...
   5 <  abc> <  345 DEF >    | 13:    ANYOF[a-z](24) # failed...
   4 <  ab> <c  345 DEF>     | 13:    ANYOF[a-z](24)
   5 <  abc> <  345 DEF >    | 24:    SUCCEED(0)
                                      subpattern success...
   0 <> <  abc  345>         | 26:IFMATCH[0](43)
   0 <> <  abc  345>         | 28:  STAR(30)
                                    REG_ANY can match 16 times out of 2147483647...
  16 <c  345 DEF  > <>       | 30:    ANYOF[A-Z](41) # failed...
  15 <c  345 DEF > < >       | 30:    ANYOF[A-Z](41) # failed...
  14 <c  345 DEF> <  >       | 30:    ANYOF[A-Z](41) # failed...
  13 <c  345 DE> <F  >       | 30:    ANYOF[A-Z](41)
  14 <c  345 DEF> <  >       | 41:    SUCCEED(0)
                                      subpattern success...
   0 <> <  abc  345>         | 43:CURLY {6,32767}(46)
                                  REG_ANY can match 16 times out of 2147483647...
  16 <c  345 DEF  > <>       | 46:  EOL(47)
  16 <c  345 DEF  > <>       | 47:  END(0)
Match successful!
Freeing REx: "^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}$"

我略微修改了输出

答案 4 :(得分:-1)

前瞻断言用于确保字符串中至少有一个数字,一个小写字母和一个大写字母。