如何在Python正则表达式中匹配重复后的Not字符

2024-03-28 15:26:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着匹配任何以1或2个1开头的数字,但如果紧接着1或2个1后有3,就不匹配了。在

我希望Regex与以下内容匹配:

1, 12, 11, 123, 111, 1113, 1123, 143, 1153, etc.

但我希望Regex匹配:

^{pr2}$

如您所见,数字必须以1开头。它可以从一个1或两个1开始,但必须至少从一个1开始。在1(s)之后,不能有3。在1或2个1之后,如果1后面没有3,则可以有任意位数(163262382983598235有效)。在

我尝试了以下模式(还有更多的模式),但没有一个有效:

re.fullmatch(r'^1{1,2}[^3].*','113')  # This matches '113' (it shouldn't), doesn't match '13' (as it shouldn't), but it also doesn't match '1' (it should)
re.fullmatch(r'^(11[^3]|1[^3]).*','113')  # Same as above
re.fullmatch(r'^(11(?!3))|(1(?!3)).*','113')  # This one actually allows '1', but it still allows '113'

(我知道“.*”匹配任何字符,而不仅仅是数字。)

我做错什么了?在


Tags: reasmatch模式etcit数字this
3条回答

这将执行以下操作(try it):

(^1{1,2}[^13].*)|(^1{3}.*)|^1{1,2}

左边的部分包括从1或2个1开始的情况(并确保后面没有1和3);中间部分包括从3个1开始的情况(然后我们不关心后面的内容);右边的部分包括“1”和“11”。在

如果我仿效Wiktor Stribiżew基于re.match()的方法,并避开{},那么为什么以下明显的简单模式不能满足需要:

import re
rx = r'([^1]|13|113)'
s = input()
m = re.match(rx, s)
if m:
    print("Invalid")
else:
    print("Valid")

也就是说,如果数字以1以外的数字开头,或以13开头或以113开头,则拒绝它。我们依赖这个模式来简单地拒绝不好的前缀,而不一定完全接受好的数字。在

这个问题是否需要“一个原子组/所有格量词解决方法”?在

我想我找到了一个更好的解决方案(至少满足我的需要)。我用消极的眼光看未来:

^(?!1{1,2}3)1{1,2}.*

说明:

^{pr2}$

最棒的是,它的工作原理与佩里贡的答案相同,但它更短,更容易阅读,更容易适应。在

编辑:

cdlane给了我一个很好的解决方案。我为re.fullmatch改编了它,它比我的原始版本更容易适应,也更短了1个字节:

^(?![^1]|1{1,2}3).*

说明:

^         # Beginning of string
(?!       # Do not match if
[^1]      # The string starts with anything other than 1
|1{1,2}3) # Or there is one or two 1s followed by a 3
.*        # Anything else is accepted

对于感兴趣的人,您还可以通过插入以下内容轻松限制开头出现的1的数量:

|1{limit,}

像这样:

^(?![^1]|1{1,2}3|1{3,}).*

如果您想更改必须出现的1的数量,而不是:

[^1]

使用:

(?!1{minimum,}

组合起来:

^(?!(?!1{4,})|1{4,5}3|1{6,}).*

相关问题 更多 >