期望如何匹配至少一个数字,一个小写,一个大写的模式

how expect match a pattern with atleast one number,one lower case ,one upper case

使用 Expect 如何检查给定的输入是否至少有一个大写字母、至少一个小写字母和至少一个数字或“!-%#”? 对于输入字符串的最小数量为10的类似问题,有人回答

expect  ^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])([!-%#])*.{10,}$

由于我是 Tcl 和 Expect 的新手,谁能解释一下上面的代码是如何工作的? 如果我们删除 {10,} 以删除最小限制,为什么它不起作用?

不能通过删除限制(绑定)量词{10,}删除最小限制,您需要替换它使用 *(允许空字符串)或 +(要求至少 1):

expect  ^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9#?!@$%^&*-]).*$

或者只是(因为 expect 不需要完整的字符串匹配):

expect  ^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9#?!@$%^&*-])

如果您需要将符号限制为前瞻内的符号,只需将 .* 替换为 [a-zA-Z0-9#?!@$%^&*-]*:

expect  ^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9#?!@$%^&*-])[a-zA-Z0-9#?!@$%^&*-]*$ 
                                                    ^^^^^^^^^^^^^^^^^^^^^

我还会在 Tcl 正则表达式中以一致的方式使用贪婪量词,尽管这对当前模式没有影响。

详情:

  • ^ - 字符串开头
  • (?=.*[A-Z]) - 在任何 0+ 个字符之后必须有一个大写 ASCII 字母
  • (?=.*[a-z]) - 在任何 0+ 个字符之后必须有一个小写 ASCII 字母
  • (?=.*[0-9#?!@$%^&*-]) - 在任何 0+ 个字符之后必须有一个 ASCII 数字,或字符 class
  • 中定义的任何特殊符号
  • .* - 任何 0+ 个字符,尽可能多到
  • $ - 字符串结尾。

(?=...) 构造被称为 正前瞻 "stand their ground",即 一旦执行它们就不会推进正则表达式索引。这样,3个lookaheads会一个一个进行校验,一旦其中一个returns为假,则整个匹配失败

注意:为了避免使用 .* 进行不必要的回溯,您可以应用 对比原则 (即在前瞻中使用相应的否定字符 classes ):

^(?=[^A-Z]*[A-Z])(?=[^a-z]*[a-z])(?=[^0-9#?!@$%^&*-]*[0-9#?!‌​@$%^&*-])[a-zA-Z0-9#‌​?!@$%^&*-]*$

[^A-Z]*会匹配一个或多个非大写ASCII字符,[^a-z]*会匹配一个或多个非小写ASCII字符等。.*抓取首先整个字符串,然后回溯,检查后续子模式是否可以匹配。因此,否定字符 classes 效率更高,并且可以更快地找到或失败匹配。