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个值,而是所有的值。为什么会这样?当它只打印出一个(值)时,它就工作了。这很奇怪。由于缺少输入数据,我没有尝试运行您的代码。但是如果你能给我们提供一些输入数据样本,我很乐意为你调试。谢谢你的帮助。我终于修好了,你的解决方案帮了大忙!