目前我有一个脚本可以查找多个输入文件中包含格式为的内容的所有行
Matches: 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])
我的正则表达式是否正确?我相信我遇到了这个问题,因为它没有正确输出。
有什么想法?我应该把它分成两个函数吗?
谢谢。
答案 0 :(得分:1)
没有。 xinpat
只匹配单个数字,因此findall()
将返回单个数字列表,这有点混乱。将其更改为
xinpat = re.compile("[\d]+")
实际上,这里不需要方括号,因此您可以将其简化为
xinpat = re.compile("\d+")
BTW,名称winpat
和xinpat
有点不透明。 pat
位正常,但是win
& xin
?并且hey
也不是很好。但我猜xin
和hey
只是你决定扩展程序时所构成的临时名称。
我刚注意到的另一件事,你不需要做
all_values.sort()
all_values.reverse()
您可以(并且应该)在一次点击中执行此操作:
all_values.sort(reverse=True)
答案 1 :(得分:1)
分数格式的正则表达式是否正确?
不,应该是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