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

标签 python regex python-3.x

我正在尝试匹配任何以一两个 1 开头的数字,但如果一两个 1 后面紧接着有一个 3,则不会匹配。

我希望正则表达式匹配以下内容:

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

但我希望正则表达式匹配:

0, 01, 21, 13, 113, 134, 11333, 135655..., etc.

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

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

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'

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

我做错了什么?

最佳答案

我想我找到了更好的解决方案(至少满足我的需要)。我使用了否定的前瞻:

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

说明:

^              # Beginning of string
(?!1{1,2}3)    # Don't match if ^ is followed by one or two 1s and a 3
1{1,2}         # One to two 1s
.*             # Anything else is accepted

最好的部分是它的工作原理与 perigon 的答案相同,但它更短,更容易阅读,并且更容易适应。

编辑:

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,}).*

关于python - 如何在 Python 正则表达式中匹配重复后的非字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45539056/

相关文章:

python - 如何从特定的 python 列表创建字典

python - 在 python 中使用线程的超时函数不起作用

regex - gsub - 将所有重复字符减少到一个实例

python - 二进制到十进制转换-公式解释

python - 将 python int 转换为 int16_t 类型

Python:如何抑制来自第三方库的日志记录语句?

在日期之间解析的 Java 正则表达式?

java - replaceAll 边界和异常(exception)

python - 自动 int 到 float 转换

python-3.x - 请求返回响应 447