匹配正则表达式中的连续数字,同时忽略 python3 re 中的破折号
Matching consecutive digits in regex while ignoring dashes in python3 re
我正在努力提高 python 中的正则表达式技能,我遇到了一个有趣的问题。假设我正在尝试匹配有效的信用卡号码,其中一个要求是它不能有 4 个或更多连续数字。 1234-5678-9101-1213 可以,但 1233-3345-6789-1011 不行。我目前有一个正则表达式,适用于没有破折号的情况,但我希望它在这两种情况下都适用,或者至少在某种程度上我可以使用 |
使其在任何一种情况下都匹配。这是我到目前为止的连续数字:
validNoConsecutive = re.compile(r'(?!([0-9]){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]){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]))
我研究了 excluding chars 和 lookahead/lookbehind 方法,但我似乎无法弄清楚。有什么方法可以忽略给定正则表达式的字符吗?感谢您的帮助!
您可以在 ^
(字符串开头)之后添加 (?!.*(\d)(?:-*){3})
否定先行以添加限制。
^(?!.*(\d)(?:-*){3})
模式匹配
^
- 字符串开头
(?!.*(\d)(?:-*){3})
- 如果在当前位置的右侧紧邻有
.*
- 除换行字符外的任何零个或多个字符尽可能多
(\d)
- 第 1 组:一位数字
(?:-*){3}
- 零个或多个 -
字符出现三次,后跟第 1 组中捕获的相同数字(因为 </code> 是对第 1 组值的内联反向引用)。 </li>
</ul>
</li>
</ul>
<p>参见<a href="https://regex101.com/r/gNM391/1" rel="nofollow noreferrer">regex demo</a>。</p>
<p>如果你想将这个模式与其他模式结合起来,只需将前瞻放在 <code>^
之后(如果你在捕获组之前有其他模式,你将需要调整 </code>反向引用)。例如。将它与你的第二个正则表达式 <code>validLength = re.compile(r'^[0-9]{16}$|^[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}$')
结合起来,它看起来像
validLength = re.compile(r'^(?!.*(\d)(?:-*){3})(?:[0-9]{16}|[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4})$')
我正在努力提高 python 中的正则表达式技能,我遇到了一个有趣的问题。假设我正在尝试匹配有效的信用卡号码,其中一个要求是它不能有 4 个或更多连续数字。 1234-5678-9101-1213 可以,但 1233-3345-6789-1011 不行。我目前有一个正则表达式,适用于没有破折号的情况,但我希望它在这两种情况下都适用,或者至少在某种程度上我可以使用 |
使其在任何一种情况下都匹配。这是我到目前为止的连续数字:
validNoConsecutive = re.compile(r'(?!([0-9]){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]){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]))
我研究了 excluding chars 和 lookahead/lookbehind 方法,但我似乎无法弄清楚。有什么方法可以忽略给定正则表达式的字符吗?感谢您的帮助!
您可以在 ^
(字符串开头)之后添加 (?!.*(\d)(?:-*){3})
否定先行以添加限制。
^(?!.*(\d)(?:-*){3})
模式匹配
^
- 字符串开头(?!.*(\d)(?:-*){3})
- 如果在当前位置的右侧紧邻有.*
- 除换行字符外的任何零个或多个字符尽可能多(\d)
- 第 1 组:一位数字(?:-*){3}
- 零个或多个-
字符出现三次,后跟第 1 组中捕获的相同数字(因为</code> 是对第 1 组值的内联反向引用)。 </li> </ul> </li> </ul> <p>参见<a href="https://regex101.com/r/gNM391/1" rel="nofollow noreferrer">regex demo</a>。</p> <p>如果你想将这个模式与其他模式结合起来,只需将前瞻放在 <code>^
之后(如果你在捕获组之前有其他模式,你将需要调整</code>反向引用)。例如。将它与你的第二个正则表达式 <code>validLength = re.compile(r'^[0-9]{16}$|^[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4}$')
结合起来,它看起来像validLength = re.compile(r'^(?!.*(\d)(?:-*){3})(?:[0-9]{16}|[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{4})$')