【问题标题】:how expect match a pattern with atleast one number,one lower case ,one upper case期望如何匹配至少一个数字、一个小写、一个大写的模式
【发布时间】:2016-09-09 07:14:37
【问题描述】:

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

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

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

【问题讨论】:

  • 那么,你只是问如何取消最小限制?将{10,} 替换为*。顺便说一句,正则表达式将检查 至少一个数字 OR "!-%#"至少一个数字和可选的“!-%#”中的可选是什么意思?如果您不需要它们,您可以将它们从前瞻中删除。
  • @Wiktor 实际上我需要整个代码的工作...您的建议可以消除限制...谢谢
  • @Wiktor 这是一个错字...已编辑

标签: regex tcl expect


【解决方案1】:

最小限制不能通过删除限制(绑定)量词{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个lookaheads会一一进行检查,一旦其中一个返回false,则整个匹配失败。

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

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

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

【讨论】:

  • 我觉得代码应该在第一部分中寻找任何字符前面的大写字母,第二部分中任何字符前面的小写字母,第三部分中任何字符前面的数字和可选的! -%# 在最后一部分...你能解释一下为什么不是这样吗?
  • 我添加了对前瞻如何工作的解释。因此,正则表达式引擎将停留在最开始并从一开始就执行 3 次检查。一旦它得到 3 次确认它可以匹配整个字符串,它就会。
  • 谢谢你 Wiktor...作为一个初学者帮助了我很多...为什么我们在最后使用 .* ,因为我们已经完成了所有必需的检查?另外如何修改代码,使其仅包含上述约束...即除了大写,小写,数字和!-#%之外的任何其他内容目前它还可以包含除此之外的任何内容,对吗?
  • 您实际上并不需要 .*$ 部分,因为 expect 不需要完整的字符串匹配。
  • 是的,我们可以这样做,它被称为对比原则^(?=[^A-Z]*[A-Z])(?=[^a-z]*[a-z])(?=[^0-9#?!@$%^&*-]*[0-9#?!@$%^&*-])[a-zA-Z0-9#?!@$%^&*-]*$。这种模式是最有效的,因为我们在使用否定字符类时不必回溯太多。
猜你喜欢
  • 1970-01-01
  • 2018-11-07
  • 2018-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-14
  • 1970-01-01
  • 2016-12-14
相关资源
最近更新 更多