2

Python3.3、OS X 7.5

我正在尝试查找定义如下的 4 字符子字符串的所有实例:

  • 第一个字符 = 'N'
  • 第二个字符 = 除了“P”之外的任何字符
  • 第三个字符 = 'S' 或 'T'
  • 第四个字符 = 除了“P”之外的任何字符

我的查询如下所示:

re.findall(r"\N[A-OQ-Z][ST][A-OQ-Z]", text)

除了在两个子字符串重叠的一种特殊情况下,这是有效的。该案例涉及以下 5 个字符的子字符串:

'...NNTSY...'

该查询捕获第一个 4 个字符的子字符串 ('NNTS'),但不捕获第二个 4 个字符的子字符串 ('NTSY')。

这是我第一次尝试正则表达式,显然我遗漏了一些东西。

4

3 回答 3

1

如果重新引擎在匹配字符时不消耗字符,则可以执行此操作,这可以通过前瞻断言来实现:

import re
text = '...NNTSY...'
for m in re.findall(r'(?=(N[A-OQ-Z][ST][A-OQ-Z]))', text):
    print(m)

输出:

NNTS
NTSY

断言中的所有内容都有效,但也感觉很奇怪。另一种方法是取消N断言:

for m in re.findall(r'(N(?=([A-OQ-Z][ST][A-OQ-Z])))', text):
    print(''.join(m))
于 2013-09-01T02:12:13.797 回答
0

来自 Python 3 文档(已添加重点):

$ python3 -c '重新导入;帮助(重新.findall)'
关于模块 re 中的 findall 函数的帮助:

findall(模式,字符串,标志=0)
    返回字符串中所有非重叠匹配的列表。

    如果模式中存在一个或多个捕获组,则返回
    组列表;这将是一个元组列表,如果模式
    有多个组。

    结果中包含空匹配项。

如果您想要重叠实例,请regex.search()在循环中使用。您必须编译正则表达式,因为非编译正则表达式的 API 不使用参数来指定起始位置。

def findall_overlapping(pattern, string, flags=0):
    """Find all matches, even ones that overlap."""
    regex = re.compile(pattern, flags)
    pos = 0
    while True:
        match = regex.search(string, pos)
        if not match:
            break
        yield match
        pos = match.start() + 1
于 2013-09-01T01:58:33.423 回答
0
(N[^P](?:S|T)[^P])

正则表达式可视化

在 Debuggex 上实时编辑

于 2013-09-01T07:08:55.163 回答