我正在努力提高我在python中的正则表达式技能,并且我遇到了一个有趣的问题。假设我正在尝试匹配有效的信用卡号码,其中一个要求是它不能有4个或更多的连续数字。1234-5678-9101-1213可以,但1233-3345-6789-1011不行。我目前有一个正则表达式,适用于当我没有破折号,但我希望它在两种情况下都能工作,或者至少在某种程度上,我可以使用|
让它匹配任何一个。以下是到目前为止我对连续数字的描述:
validNoConsecutive = re.compile(r'(?!([0-9])1{4,})')
我知道我可以用''
代替'-'
,但是为了使我的代码更通用,它会更容易,只是一个正则表达式。下面是更多上下文的函数:
def isValid(number):
validStart = re.compile(r'^[456]') # Starts with 4, 5, or 6
validLength = re.compile(r'^[0-9]{16}$|^[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}$') # is 16 digits long
validOnlyDigits = re.compile(r'^[0-9-]*$') # only digits or dashes
validNoConsecutive = re.compile(r'(?!([0-9])1{4,})') # no consecutives over 3
validators = [validStart, validLength, validOnlyDigits, validNoConsecutive]
return all([val.search(number) for val in validators])
list(map(print, ['Valid' if isValid(num) else 'Invalid' for num in arr]))
我研究了排除字符和向前看/向后看方法,但我似乎不能弄清楚。是否有某种方法可以忽略给定正则表达式中的字符?谢谢你的帮助!
您可以在^
(字符串的开始)之后添加(?!.*(d)(?:-*1){3})
负向前看来添加限制
^(?!.*(d)(?:-*1){3})
模式匹配
^
-字符串 起始(?!.*(d)(?:-*1){3})
-如果在当前位置的右边有,则会导致匹配失败.*
-除换行符外的任何零个或多个字符尽可能多(d)
-第1组:1位(?:-*1){3}
-出现三次零或更多-
字符,后面跟着在第1组中捕获的相同数字(因为1
是对第1组值的内联反向引用)。
查看regex演示
如果您想将此模式与其他模式结合起来,只需将forward放在^
之后(如果您在捕获组之前有其他模式,则需要调整1
反向引用)。例如,将它与第二个正则表达式validLength = re.compile(r'^[0-9]{16}$|^[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}$')
结合起来,它看起来像
validLength = re.compile(r'^(?!.*(d)(?:-*1){3})(?:[0-9]{16}|[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4})$')