Python 使用re比较多个文件项
目前,我有一个脚本,可以查找多个输入文件中的所有行,这些行的格式为Python 使用re比较多个文件项,python,regex,file-io,Python,Regex,File Io,目前,我有一个脚本,可以查找多个输入文件中的所有行,这些行的格式为 匹配:500个(54.3%)并打印出百分比最高的前10个匹配项 我希望它也能输出得分前10行,例如:得分:4000 import re def get_values_from_file(filename): f = open(filename) winpat = re.compile("([\d\.]+)\%") xinpat = re.compile("[\d]") #ISSUE, is this t
匹配:500个(54.3%)
并打印出百分比最高的前10个匹配项
我希望它也能输出得分前10行,例如:得分:4000
import re
def get_values_from_file(filename):
f = open(filename)
winpat = re.compile("([\d\.]+)\%")
xinpat = re.compile("[\d]") #ISSUE, is this the right regex for it? Score: 500****
values = []
scores = []
for line in f.readlines():
if line.find("Matches") >=0:
percn = float(winpat.findall(line)[0])
values.append(percn)
elif line.find("Score") >=0:
hey = float(xinpat.findall(line)[0])
scores.append(hey)
return (scores,values)
all_values = []
all_scores = []
for filename in ["out0.txt", "out1.txt"]:#and so on
values = get_values_from_file(filename)
all_values += values
all_scores += scores
all_values.sort()
all_values.reverse()
all_scores.sort() #also for scores
all_scores.reverse()
print(all_values[0:10])
print(all_scores[0:10])
我的分数格式正则表达式正确吗?我认为这就是问题所在,因为它不能正确输出这两种格式
有什么想法吗?我应该把它分成两个功能吗
谢谢。否。
xinpat
将只匹配个位数,因此findall()
将返回个位数列表,这有点混乱。换成
xinpat=re.compile([\d]+”)
实际上,这里不需要方括号,所以可以简化为
xinpat=re.compile(“\d+”)
顺便说一句,名字winpat
和xinpat
有点不透明。pat
位正常,但是win
和xin
?而且嘿
也不太好。但是我想,xin
和hey
只是你决定扩展程序时临时拼凑的名字
我刚刚注意到的另一件事,你不需要做
all_values.sort()
all_values.reverse()
你可以(也应该)一次完成:
all_values.sort(reverse=True)
我的分数格式正则表达式正确吗
不,它应该是r“\d+”
- 您不需要
。这些括号建立了一个字符类,表示括号内的所有字符。由于括号内只有一种字符类型,因此它们不起任何作用[]
- 您只匹配一个字符。您需要一个
或*
来匹配字符序列+
- 您的字符串中有一个未经转换的反斜杠。使用
前缀允许正则表达式引擎看到反斜杠r
line.find()
:
#UNTESTED
def get_values_from_file(filename):
winpat = re.compile(r"Matches:\s*\d+\s*\(([\d\.]+)\%\)")
xinpat = re.compile(r"Score:\s*([\d]+)")
values = []
scores = []
# Note: "with open() as f" automatically closes f
with open(filename) as f:
# Note: "for line in f" more memory efficient
# than "for line in f.readlines()"
for line in f:
win = winpat.match(line)
xin = xinpat.match(line)
if win: values.append(float(win.group(0)))
if xin: scores.append(float(xin.group(0)))
return (scores,values)
为了好玩,这里有一个版本的例程,每个文件只调用一次re.findall
:
# TESTED
# Compile this only once to save time
pat = re.compile(r'''
(?mx) # multi-line, verbose
(?:Matches:\s*\d+\s*\(([\d\.]+)\s*%\)) # "Matches: 300 (43.2%)"
|
(?:Score:\s*(\d+)) # "Score: 4000"
''')
def get_values_from_file(filename):
with open(filename) as f:
values, scores = zip(*pat.findall(f.read()))
values = [float(value) for value in values if value]
scores = [float(score) for score in scores if score]
return scores, values
在示例格式中,似乎在“54.3”和“%”之间存在空格字符。要处理该空间,第一个正则表达式模式应该是“winpat=re.compile(([\d\.]+)\s\%”)。(我在number和percentaga之间添加了空格(\s))因为我们看不到输入,你能给出一个示例输出吗?@Fumu7:我怀疑空格是一个转录错误,因为user3295674说
winpat
东西工作正常。但是如果我们想处理一个可能的空格,那么'([\d.]+)\s*%'
或'([\d.]+)\s?%
会更好。@user3295674您能不能在下修复[“out0.txt”,“out1.txt]”中文件名的缩进:
。此外,还有一个打字/转录错误values=get\u values\u from\u file(文件名)
应该是scores,values=get\u values\u from\u file(文件名)
+1这也是我的想法。因为他只从findall获取第一个t结果。当然,如果我真的很酷的话,我会将这两个正则表达式组合起来,这样每个输入行只有一个调用.match()
。至于使用match()
(或search()
)而不是'findall(),我同意。但我不知道如何组合正则表达式。我认为正则表达式的内容应该尽可能简单(但不能更简单:)。合并正则表达式会使代码的其余部分稍微复杂一些。但是比较两种方法的速度会很有趣……好的,罗伯。你的新版本很好。谢谢,是的,它们现在是测试变量,但很好的一点。我更改了正则表达式,这一个可以工作,但由于某种原因,当我打印(所有的_分数[0:10]),所有的_值都是一样的,它不会输出前10个值,而是所有的值。为什么会这样?当它只打印出一个(值)时,它就工作了。这很奇怪。由于缺少输入数据,我没有尝试运行您的代码。但是如果你能给我们提供一些输入数据样本,我很乐意为你调试。谢谢你的帮助。我终于修好了,你的解决方案帮了大忙!