我正在尝试编写一些正则表达式,它将匹配包含4个或更多字母的字符串,这些字母不一定按顺序排列。
输入字符串可以混合使用大写和小写字母,数字,非字母字符等,但我只希望它通过正则表达式测试,如果它包含至少4个大写或小写字母。
我希望成为有效输入的示例如下所示:
a124Gh0st
我目前正在编写这段正则表达式:
(?(?=[a-zA-Z])([a-zA-Z])| )
成功返回5个匹配项,但只要输入字符串中包含大于1个字母,它就会一直传递。如果我将{4,}添加到它的末尾然后它可以工作,但仅限于连续有4个字母的情况。
我使用以下网站测试我一直在做的事情:regex101
对此的任何帮助将不胜感激。
答案 0 :(得分:4)
您可以使用
(?s)^([^a-zA-Z]*[A-Za-z]){4}.*
或
^([^a-zA-Z]*[A-Za-z]){4}[\s\S]*
请参阅regex demo。
详细:
^
- 字符串开头([^a-zA-Z]*[A-Za-z]){4}
- 正好有4个序列:
[^a-zA-Z]*
- 除ASCII字母以外的0 +字符[A-Za-z]
- ASCII字母[\S\s]*
- 任何0+字符(如果启用了DOTALL修饰符,则与.*
相同)。答案 1 :(得分:1)
为什么不匹配每个字母之间的零个或多个字符?例如,
(?:[A-Za-z].*){4}
你会认出[A-Za-z]
。 .
匹配任何字符,因此.*
是任何字符的任意数字(包括零)的运行。一组字母后跟任意数量的任何字符重复四次,因此当且仅当字符串中至少出现四个字母时,此模式才匹配。 (请注意,模式第四次重复的尾随.*
大部分是无关紧要的,因为它可以匹配零个字符。)
如果您使用的是支持不情愿量词的正则表达式语言,那么使用它们将使这种模式更加高效。例如,在Java或Perl中,人们可能更喜欢使用
(?:[A-Za-z].*?){4}
.*?
仍然匹配任何数字的任何字符,但匹配算法将匹配每个此类运行的尽可能少的字符。这将减少它需要执行的回溯量。对于这种特殊模式,它会将所需的回溯减少到零。
如果你的正则表达方言中没有不情愿的量词,那么你可以更加冗长地达到同样的效果:
(?:[A-Za-z][^A-Za-z]*?){4}
在那里,只有非字母匹配字母之间的运行。
即使这样,该模式也使用了所有正则表达式中不存在的一些正则表达式功能 - 非捕获组,枚举量词 - 但这些都存在于您的原始正则表达式中。对于最大兼容的表单,您可以编写
[A-Za-z][^A-Za-z]*[A-Za-z][^A-Za-z]*[A-Za-z][^A-Za-z]*[A-Za-z]