提问人:csharp1321 提问时间:10/30/2023 更新时间:10/30/2023 访问量:53
使用正则表达式 Python 3 指定多个匹配“长度”
Specify Multiple Match "Lengths" with Regex Python 3
问:
我是正则表达式的新手,不知道该如何问这个问题,但我会尽力而为。
这是我正在使用的一个简单的表达式:
"^[0-9]{13}$"
这与长度正好为 13 个字符的数字字符串匹配。根据 Python 文档,我可以设置一个这样的范围,该范围将与长度在 13 到 20 个字符之间的任意数字字符串匹配,例如:
"^[0-9]{13,20}$"
我的问题是,如何从范围中排除某些“长度”?例如:
"^[0-9]{13,20 EXCEPT for 15 or 17}$"
在该示例中,我想包括 13 到 20 之间的任何长度,但 15 和 17 除外。
这可能吗?
我已经查看了 Python 3 正则表达式文档,但我个人找不到一种方法来做到这一点,但我也没有经验,所以我可能会忽略一些东西。
答:
0赞
InSync
10/30/2023
#1
井。。。是的,你可以,但这需要的不仅仅是一个量词。
^
(?:
[0-9]{13,14} # 13 or 14
|
[0-9]{16} # or 16
|
[0-9]{18,20} # or 18, 19, 20.
)
$
展望:
^
(?!.{15}$)(?!.{17}$) # Assure that the length is neither 15 nor 17,
[0-9]{13,20} # and at the same time, 13 <= length <= 20.
$
使用回溯:
^
[0-9]{13,20} # Basically the same pattern,
(?<!^.{15})(?<!^.{17}) # just inverted.
$
使用普通的 Python 代码:
# Note the lack of anchors and the use of .fullmatch()
# That method is used here since it is more readable,
# and it automatically adds anchors.
_13_to_20_digits = re.compile('[0-9]{13,20}')
if _13_to_20_digits.fullmatch(text) and len(text) not in (15, 17):
frobnicate()
选择一个。随心所欲。就我个人而言,我喜欢最后一个,因为它非常清楚,即使对于那些不知道正则表达式的人来说也是如此。[需要引证]
0赞
Timeless
10/30/2023
#2
在第二种模式中,您可以将字符串的开头替换为自定义/受限制的字符串开头(根据要排除的长度构建)。这将确保匹配字符串的每个开头,但前提是此字符串的长度不是 15 或 17 个字符。^
^(?!(.{15}|.{17})$)
Use^(?!(.{15}|.{17})$)[0-9]{13,20}$
instead of^[0-9]{13,20}$
下面是一个通用代码来处理不同的不连续范围:
# feel free to adjust the values
(l, r), excep = [13, 20], [15, 17]
to_excl = "|".join(".{%s}" % n for n in excep)
pat = re.compile(r"^(?!(%s)$)[0-9]{%s,%s}$" % (to_excl, l, r))
测试/输出 :
for t in text:
print(
f"{t:<22}", f"{len(t):<4}",
"match" if pat.match(t) else "no-match"
)
01234 5 no-match
012345678901234 15 no-match
0123456789012345 16 match
01234567890123456 17 no-match
012345678901234567 18 match
012345678901234567890 21 no-match
使用的输入:
from string import digits
s = digits; lens = [5, 15, 16, 17, 18, 21]
text = [s * (l // 10) + s[:l % 10] for l in lens]
['01234',
'012345678901234',
'0123456789012345',
'01234567890123456',
'012345678901234567',
'012345678901234567890']
评论
1赞
csharp1321
10/30/2023
这太完美了!感谢您的帮助和见解!
评论
^(?!.{15}$)(?!.{17}$)[0-9]{13,20}$
- 两个否定展望拒绝任何属于禁止长度之一的字符串。并不是说这是实现您的要求的好方法,只是说这是可能的。^[0-9]{13}([0-9]([0-9][0-9]([0-9][0-9]{1,3})?)?)?$
,但 Jason 的正则表达式更具可读性