首页 > 解决方案 > 多行正则表达式匹配检索行号和匹配

问题描述

我正在尝试遍历文件中的所有行以匹配可能的模式;

  1. 出现在文件的任何地方
  2. 在同一个文件中多次出现
  3. 在同一行多次出现
  4. 对于一个正则表达式模式,我正在搜索的字符串可以分布在多行中

一个示例输入是;

new File()
new
File()
there is a new File()
new
    
    
    
File()
there is not a matching pattern here File() new
new File() test new File() occurs twice on this line

示例输出是;

new File() Found on line 1  
new File() Found on lines 2 & 3 
new File() Found on line 4 
new File() Found on lines 5 & 9 
new File() Found on line 11
new File() Found on line 11 
6 occurrences of new File() pattern in test.txt (Filename)

正则表达式模式看起来像;

pattern = r'new\s+File\s*\({1}\s*\){1}'

查看此处的文档,我可以看到 match、findall 和 finditer 都在字符串的开头返回匹配项,但我没有看到使用搜索函数的方法,该函数在任何位置查找我们正在搜索的字符串的正则表达式for 超过多行(上面我的要求中的第四个)。

足够简单,可以匹配每行不止一次出现的正则表达式;

示例输入:

line = "new File() new File()"

代码:

i = 0
matches = []
while i < len(line):
    while line:
        matchObj = re.search(r"new\s+File\s*\({1}\s*\){1}", line, re.MULTILINE | re.DOTALL)
        if matchObj:
            line = line[matchObj.end():]
            matches.append(matchObj.group())

print(matches)

打印以下匹配项 - 目前不包括行号等:

['new File()', 'new File()']

有没有办法用 Python 的正则表达式来做我正在寻找的东西?

标签: pythonpython-3.xregex

解决方案


您可以首先找到\n文本中的所有字符及其各自的位置/字符索引。由于每个\n...well... 开始一个新行,因此此列表中每个值的索引表示找到的\n字符终止的行号。然后搜索所有出现的模式并使用上述列表查找匹配的开始/结束位置......

import re
import bisect

text = """new 
File()
aa new File()
new
File()
there is a new File() and new
File() again
new
    
    
    
File()
there is not a matching pattern here File() new
new File() test new File() occurs twice on this line
"""

# character indices of all \n characters in text
nl = [m.start() for m in re.finditer("\n", text, re.MULTILINE|re.DOTALL)]

matches = list(re.finditer(r"(new\s+File\(\))", text, re.MULTILINE|re.DOTALL))
match_count = 0
for m in matches:
    match_count += 1
    r = range(bisect.bisect(nl, m.start()-1), bisect.bisect(nl, m.end()-1)+1)
    print(re.sub(r"\s+", " ", m.group(1), re.DOTALL), "found on line(s)", *r)
print(f"{match_count} occurrences of new File() found in file....")

输出:

new File() found on line(s) 0 1
new File() found on line(s) 2
new File() found on line(s) 3 4
new File() found on line(s) 5
new File() found on line(s) 5 6
new File() found on line(s) 7 8 9 10 11
new File() found on line(s) 13
new File() found on line(s) 13
8 occurrences of new File() found in file....

推荐阅读