如何查找regex匹配的行



我有一个多行字符串,希望在Python中对其应用正则表达式。有没有办法找出正则表达式在哪一行匹配?

例如,如果我使用regex

regex = re.compile("(?<=i)s")

字符串

s = """This
is
a multiline
string"""

我怎么能发现01行匹配?regex.findall(s)给了我一个所有匹配项的列表,但它没有告诉我这些匹配项在哪一行。

如果使用regex.finditer,则可以获得如下行号:

regex = re.compile("(?<=i)s")
s = """This
is
a multiline
string"""
for match in regex.finditer(s):
    lineno = s.count('n', 0, match.start())
    ...

您可以使用enumerate()来获取行号:

>>> regex = re.compile("(?<=i)s")
>>> results = []
>>> for lineno, line in enumerate(s.split("n")):
...     if regex.search(line):
...         results.append((lineno, line))
...
>>> results
[(0, 'This'), (1, 'is')]

当然,如果您不需要行本身的内容,只需执行results.append(lineno)即可。

一个简单的方法是交替匹配换行符:

lineno=1
for m in re.findall(r'n|(?<=i)s', s):
    if m != 'n': print lineno, m
    else : lineno += 1

如果使用re.MULTILINE,则插入符号(^)在字符串的开头和行的开头匹配。稍微更改正则表达式,会得到一个所有行的列表,其中有一个不匹配的空字符串:

>>> regex = re.compile("(^.*(?<=i)s|^)", re.MULTILINE)
>>> regex.findall(s)
['This', 'is', '', '']

行号是索引加上字符串不为空的列表中的一个:

>>> [(i + 1, j) for (i, j) in enumerate(regex.findall(s)) if j != '']
[(1, 'This'), (2, 'is')]

对于您在评论中提出的第二个问题,

您可以使用reStringIO

import re
from StringIO import StringIO
s = """This
is
a multiline
string.
This is a line with several "is""""
print s
rgx = re.compile("(?<=i)s")
def graou(s):
    sl = 0
    for i,line in enumerate(StringIO(s)):
        tu = tuple(sl+m.start() for m in rgx.finditer(line))
        if tu: yield (i,tu)
        sl += len(line)
print [x for x in graou(s) if x[1]]

要么只使用re(我更喜欢):

import re
s = """This
is
a multiline
string.
This is a line with several "is""""
print s
rgx = re.compile('$|(?<=i)s',re.MULTILINE)
def graou(s):
    i,li = 0,[]
    for m in rgx.finditer(s):
        if m.group()!='':
            li.append(m.start())
        elif li:
            yield((i,tuple(li)))
            i += 1
            li = []

最新更新