在文件对象中匹配多行正则表达式
我该如何从一个文件对象(data.txt)中提取这个正则表达式的分组?
import numpy as np
import re
import os
ifile = open("data.txt",'r')
# Regex pattern
pattern = re.compile(r"""
^Time:(\d{2}:\d{2}:\d{2}) # Time: 12:34:56 at beginning of line
\r{2} # Two carriage return
\D+ # 1 or more non-digits
storeU=(\d+\.\d+)
\s
uIx=(\d+)
\s
storeI=(-?\d+.\d+)
\s
iIx=(\d+)
\s
avgCI=(-?\d+.\d+)
""", re.VERBOSE | re.MULTILINE)
time = [];
for line in ifile:
match = re.search(pattern, line)
if match:
time.append(match.group(1))
代码的最后部分有个问题,就是我一行一行地遍历,这显然不适合多行的正则表达式。我试着用 pattern.finditer(ifile)
这样的方法:
for match in pattern.finditer(ifile):
print match
...只是想看看是否有效,但 finditer 方法需要一个字符串或缓冲区。
我也试过这种方法,但就是无法让它工作
matches = [m.groups() for m in pattern.finditer(ifile)]
有什么想法吗?
在Mike和Tuomas的评论后,我被建议使用 .read().. 类似这样:
ifile = open("data.txt",'r').read()
这样可以正常工作,但这真的是查找文件的正确方法吗?我就是无法让它工作...
for i in pattern.finditer(ifile):
match = re.search(pattern, i)
if match:
time.append(match.group(1))
解决方案
# Open file as file object and read to string
ifile = open("data.txt",'r')
# Read file object to string
text = ifile.read()
# Close file object
ifile.close()
# Regex pattern
pattern_meas = re.compile(r"""
^Time:(\d{2}:\d{2}:\d{2}) # Time: 12:34:56 at beginning of line
\n{2} # Two newlines
\D+ # 1 or more non-digits
storeU=(\d+\.\d+) # Decimal-number
\s
uIx=(\d+) # Fetch uIx-variable
\s
storeI=(-?\d+.\d+) # Fetch storeI-variable
\s
iIx=(\d+) # Fetch iIx-variable
\s
avgCI=(-?\d+.\d+) # Fetch avgCI-variable
""", re.VERBOSE | re.MULTILINE)
file_times = open("output_times.txt","w")
for match in pattern_meas.finditer(text):
output = "%s,\t%s,\t\t%s,\t%s,\t\t%s,\t%s\n" % (match.group(1), match.group(2), match.group(3), match.group(4), match.group(5), match.group(6))
file_times.write(output)
file_times.close()
也许可以写得更简洁、更符合Python风格……
3 个回答
1
你为什么不把整个文件读到一个缓冲区里,使用
buffer = open("data.txt").read()
然后再用这个缓冲区进行搜索呢?
3
times = [match.group(1) for match in pattern.finditer(ifile.read())]
finditer
会返回 MatchObjects
。如果正则表达式没有匹配到任何内容,times
就会是一个空列表。
你也可以修改你的正则表达式,使用不捕获的分组来处理 storeU
、storeI
、iIx
和 avgCI
,这样 pattern.findall
只会包含匹配到的时间。
注意:把变量命名为 time
可能会和标准库中的模块冲突。使用 times
会是个更好的选择。
5
你可以使用 ifile.read()
这个方法,把文件里的数据读进一个字符串里。