作为较大的正则表达式的一部分,我希望符合以下限制:
这意味着以下内容应匹配:
12345678914
12235879600
而这些不应:
12345678903 -> none of the numbers at digits 1 to 10 appears twice
14427823482 -> one number appears more than twice
72349121762 -> two numbers appear twice
我试图使用前瞻性,但是我要管理的是正则表达式计数某个数字,即:
(?!.*0\1{2})
那不能满足我的需求。使用regex甚至可以查询吗?
您可以使用这种模式:
\A(?=\d{11}\z)(?:(\d)(?!\d*\1\d))*(\d)(?=\d*\2\d)(?:(\d)(?!\d*\3\d))+\d\z
图案细节:
想法是将字符串描述为重复的数字,并用非重复的数字包围。
通过捕获组,先行断言和后向引用,可以轻松找到重复的数字:(\d)(?=\d*\1)
您可以使用相同的模式来确保数字没有重复,但是这次的前瞻性为负: (\d)(?!\d*\1)
要在重复搜索中不考虑最后一位数字(n°11位),您只需要在反向引用之后添加一位数字。(\d)(?=\d*\1\d)
(通过这种方式,您可以确保在反向引用和字符串末尾之间至少有一个数字。)
注意,在当前上下文中,所谓的重复数字是指没有立即或稍后跟随相同数字的数字。(即,1234567891
第一个1
是重复数字,但最后一个1
不再是重复数字,因为它后面没有另一个1
)
\A # begining of the string
(?=\d{11}\z) # check the string length (if not needed, remove it)
(?:(\d)(?!\d*\1\d))* # zero or more non duplicate digits
(\d)(?=\d*\2\d) # one duplicate digit
(?:(\d)(?!\d*\3\d))+ # one or more non duplicate digits
\d # the ignored last digit
\z # end of the string
其他方式
这次,您使用先行模式在模式的开头检查重复项。一个前瞻以确保有一个重复的数字,一个否定前瞻以确保没有两个重复的数字:
\A(?=\d*(\d)(?=\d*\1\d))(?!\d*(\d)(?=\d*\2\d)\d*(\d)(?=\d*\3\d))\d{11}\z
图案细节:
\A
(?= # check if there is one duplicate digit
\d*(\d)(?=\d*\1\d)
)
(?! # check if there are not two duplicate digits
\d*(\d)(?=\d*\2\d) # the first
\d*(\d)(?=\d*\3\d) # the second
)
\d{11}
\z
注意:但是,第一种方法似乎更有效。
编码方式
您可以使用数组方法轻松检查您的字符串是否符合要求:
> mydigs = "12345678913"
=> "12345678913"
> puts (mydigs.split(//).take 10).uniq.size == 9
true
=> nil
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句