使用Expect如何检查给定输入是否至少有一个大写字母,至少一个小写字母和至少一个数字或“! - %#”? 对于输入字符串的最小数量为10的类似问题,有人回答
expect ^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])([!-%#])*.{10,}$
由于我是Tcl和Expect的新手,有人可以解释一下上述代码是如何工作的吗?
如果我们删除{10,}
以删除最低限制,为什么它不起作用?
答案 0 :(得分:2)
删除限制(绑定)量词{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数字,或字符类中定义的任何特殊符号.*
- 任意0个字符,最多可达$
- 字符串的结尾。 (?=...)
构造被称为正向前瞻“坚持自己的立场”,即一旦执行它们就不会提升正则表达式索引。因此,3个前瞻将逐个执行检查,一旦其中一个返回false,整个匹配将失败。
注意:为了避免使用.*
进行不必要的回溯,您可以应用对比原理(即在前瞻中使用相应的否定字符类):
^(?=[^A-Z]*[A-Z])(?=[^a-z]*[a-z])(?=[^0-9#?!@$%^&*-]*[0-9#?!@$%^&*-])[a-zA-Z0-9#?!@$%^&*-]*$
[^A-Z]*
将匹配大写ASCII字母以外的一个或多个字符,[^a-z]*
将匹配小写ASCII字母以外的一个或多个字符,等等。.*
抓取整个字符串首先,然后回溯,检查后续子模式是否匹配。因此,否定的字符类更有效,并且可以更快地找到或失败匹配。