Regex 任意数字的两个,然后是另一个数字的三个,然后是另一个数字的四个?
正则表达式很棒,但我一辈子都搞不清楚如何表达以下约束条件,而不详细说明整个排列:Regex 任意数字的两个,然后是另一个数字的三个,然后是另一个数字的四个?,regex,Regex,正则表达式很棒,但我一辈子都搞不清楚如何表达以下约束条件,而不详细说明整个排列: 2 of any digit [0-9] 3 of any other digit [0-9] excluding the above 4 of any third digit [0-9] excluding the above 我有一个怪物,这显然不是一个好办法,因为它随着每一组额外的数字呈指数增长: ^(001112222|001113333|001114444|001115555|001116666|000
2 of any digit [0-9]
3 of any other digit [0-9] excluding the above
4 of any third digit [0-9] excluding the above
我有一个怪物,这显然不是一个好办法,因为它随着每一组额外的数字呈指数增长:
^(001112222|001113333|001114444|001115555|001116666|0001117777|0001118888|0001119999|0002220000|...)$
OR
^(0{2}1{3}2{4}|0{2}1{3}3{4}|0{2}1{3}4{4}|0{2}1{3}5{4}|0{2}1{3}6{4}|0{2}1{3}7{4}|0{2}1{3}8{4}|...)$
根据您的目标环境/框架/语言是否支持lookaheads,您可以执行以下操作:
^(\d)\1(?!\1)(\d)\2\2(?!\1|\2)(\d)\3\3\3$
第一个捕获组((\d)
)允许我们通过引用捕获值(\1
)作为下一个匹配来强制执行“两个相同的连续数字”,之后负前瞻确保下一个序列不会从前一个数字开始-然后我们只需重复此模式两次
注意:如果只想排除前一个序列中使用的数字,请将
(?!\1 |\2)
更改为仅(?!\2)
,看起来以下操作可行:
^((\d)\2(?!.+\2)){2}\2(\d)\3{3}$
使用递归模式可能看起来有点棘手,但它可能看起来比实际情况更吓人。请参阅联机
-启动字符串锚定^
-打开第一个捕获组:(
-第二个捕获组,可捕获0-9之间的单个数字(\d)
-对第二组中捕获内容的反向引用\2
-负向前看,以防止1+个字符后跟对第二组匹配项的反向引用(?!.+\2)
-关闭第一个捕获组并将其匹配两次){2}
-对第二个捕获组中最近捕获的内容的反向引用\2
-第三个捕获组,包含一个数字(\d)
-第三个捕获组的匹配正好有三个反向引用\3{3}
-结束字符串锚定$
编辑: 看看你的备选方案,看起来你也允许像“00222000”这样的数字,只要每个序列中的数字与之前的数字序列不同。如果是这种情况,您可以将上述内容简化为:
^((\d)\2(?!.\2)){2}\2(\d)\3{3}$
主要的区别是“+”修饰符已从模式中删除,以允许进一步使用相同的数字
请参见为什么不在垂直条上拆分,然后编写一个简单的解析器来检查每个字符串。我刚刚注意到,在OP的替换中,他提到了“00222000”之类的东西,这意味着只要前面的数字序列不同,他可能会允许。只是一个headup=)@JvdV很好的捕获,更新了答案,并附上了一条关于它的注释,谢谢