2

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

例如,如果我使用正则表达式

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

在弦上

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

我怎样才能找到那条线01匹配?regex.findall(s)给了我所有匹配项的列表,但它没有告诉我这些匹配项在哪一行。

4

5 回答 5

4

如果你使用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())
    ...
于 2013-07-06T12:12:07.177 回答
3

您可以使用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).

于 2013-07-06T12:03:24.877 回答
3

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

lineno=1
for m in re.findall(r'\n|(?<=i)s', s):
    if m != '\n': print lineno, m
    else : lineno += 1
于 2013-07-06T12:22:11.950 回答
2

如果使用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')]
于 2013-07-06T12:24:20.453 回答
1

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

您可以使用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 = []
于 2013-07-06T16:41:52.503 回答