【问题标题】:Python issue with printing regex group from log file从日志文件打印正则表达式组的 Python 问题
【发布时间】:2020-02-22 21:28:29
【问题描述】:

我在从日志文件中打印两个正则表达式组时遇到了困难。我没有得到任何错误,只是没有得到任何结果。

我希望他们读作:

12345@email.com = 19290 45678@email.com = 23625

在这种情况下,我只想打印 category2 中的帐户和高分数据。我对 Python 很陌生,但我正在尝试通过实践来学习更多。似乎我的正则表达式在 python 中没有返回任何匹配项,但是当我使用这个Regex101 工具时,我得到了两个组和我的正则表达式代码。也许问题是我如何打印这些组。 任何帮助将不胜感激,以便我可以从错误中吸取教训。 :)

这是我的代码:

import re

log = open(r"C:\CurrentLog.txt","r")
regex = re.compile("Category2-{25}\n.{51}(?P<Account>.{11}\.com).\.\.(?:$\n^.*){5}High Score = (?P<Score>\d{2,})", re.M)

for line in log:
    data = regex.findall(line)
    for word in data:
        print (line.group(Account))
        print (line.group(Score))

日志文件示例:

实际的日志文件将保持在 400 - 600 行左右,所以我不必担心将其加载到内存中。

2019-10-17 17:56:44,295 :: INFO :: root :: -------------------------Category1-------------------------
2019-10-17 17:56:49,988 :: INFO :: root :: Account 12345@email.com...
2019-10-17 17:57:09,328 :: INFO :: root :: other info 1
2019-10-17 18:00:22,267 :: INFO :: root :: other info 2
2019-10-17 18:00:22,582 :: INFO :: root :: High Score = 19090
2019-10-17 18:00:22,582 :: INFO :: root :: other info 3
2019-10-17 18:00:22,582 :: INFO :: root :: other info 4
2019-10-17 18:00:24,661 :: INFO :: root :: -------------------------Category2-------------------------
2019-10-17 18:00:29,619 :: INFO :: root :: Account 12345@email.com...
2019-10-17 18:00:46,317 :: INFO :: root :: other info 1
2019-10-17 18:05:46,088 :: INFO :: root :: other info 2
2019-10-17 18:05:52,451 :: INFO :: root :: other info 3
2019-10-17 18:08:11,765 :: INFO :: root :: other info 4
2019-10-17 18:08:12,813 :: INFO :: root :: High Score = 19290
2019-10-17 18:08:12,814 :: INFO :: root :: other info 5
2019-10-17 18:08:12,814 :: INFO :: root :: other info 6
2019-10-17 18:08:14,890 :: INFO :: root :: -------------------------Category1-------------------------
2019-10-17 18:08:19,860 :: INFO :: root :: Account 45678@email.com...
2019-10-17 18:08:37,188 :: INFO :: root :: other info 1
2019-10-17 18:13:23,232 :: INFO :: root :: other info 2
2019-10-17 18:13:23,595 :: INFO :: root :: High Score = 23425
2019-10-17 18:13:23,595 :: INFO :: root :: other info 3
2019-10-17 18:13:23,595 :: INFO :: root :: other info 4
2019-10-17 18:13:25,689 :: INFO :: root :: -------------------------Category2-------------------------
2019-10-17 18:13:30,660 :: INFO :: root :: Account 45678@email.com...
2019-10-17 18:13:47,727 :: INFO :: root :: other info 1
2019-10-17 18:16:20,327 :: INFO :: root :: other info 2
2019-10-17 18:16:26,907 :: INFO :: root :: other info 3
2019-10-17 18:18:44,376 :: INFO :: root :: other info 4
2019-10-17 18:18:45,447 :: INFO :: root :: High Score = 23625
2019-10-17 18:18:45,447 :: INFO :: root :: other info 5
2019-10-17 18:18:45,447 :: INFO :: root :: other info 6

如果您需要更多信息或上下文,请告诉我。

谢谢!

【问题讨论】:

    标签: python regex python-3.x regex-group


    【解决方案1】:

    下面的代码可以帮助你。我会给你一个包含电子邮件和分数的元组列表。

    log_text = open(r"log.txt", "r").read()
    regex = re.compile(r"Category2-{25}\n.{51}(?P<Account>.{11}\.com).\.\.(?:$\n^.*){5}High Score = (?P<Score>\d{2,})", re.M)
    print(regex.findall(log_text))
    

    输出

    [('12345@email.com', '19290'), ('45678@email.com', '23625')]
    

    【讨论】:

      【解决方案2】:
      for line in log:
          data = regex.findall(line)
      

      上面的代码块正在做的是在每一行上应用你的正则表达式,这将失败,因为你的正则表达式跨越多行。您需要在整个内容上使用您的正则表达式。

      下面的代码应该可以正常工作

      import re
      # Read the entire content from file into a variable
      contents = open(r"log.txt", "r").read()
      regex = re.compile("Category2-{25}\n.{51}(?P<Account>.{11}\.com).\.\.(?:$\n^.*){5}High Score = (?P<Score>\d{2,})", re.M)
      
      # Find iter is like re.findall, just that it returns the captured regex group objects(Also that it returns a callable iterator, but thats not important to know here)
      for match in regex.finditer(contents):
          print match.group('Account')
          print match.group('Score')
      

      【讨论】:

        【解决方案3】:

        我觉得你把Regex 复杂了一点试试这个:

        RE_PATTERN = re.compile(r'Account\s(?P<Account>.+?\.com).*?High Score = (?P<Score>\d+)', re.DOTALL)
        
        #  read the entire the log as a text 
        for match in RE_PATTERN.finditer(log.read()):
            print(match.group('Account'))
            print(match.group('Score'))
        

        使用re.DOTALL. 将匹配\n,因此.*? 将消耗任何东西,直到找到单词High Score =

        【讨论】:

        • 一件事将整个日志文本传递给这个regex
        【解决方案4】:

        你可以试试你的正则表达式的简化版本:Category2-{25}\n.+Account\s+(.+)[\s\S]+?High Score = (.+)

        Account\s+(.+) - 将匹配Account 和一个或多个空格,因此它将匹配到电子邮件地址,然后将匹配所有内容,直到换行符(即整个电子邮件地址)并将其存储在捕获组中。

        另一个修改是[\s\S]+?,它匹配每个字符,一个或多个,非贪婪的,直到匹配High Score。然后它匹配并在第二个捕获组中存储分数(在等号之后)。

        Demo

        【讨论】:

        • 我查看了您的简化正则表达式的方法,它确实以更优雅的方式找到了我正在寻找的值。如果垃圾文本进入,它甚至可能更能抵抗日志文件中的不一致。唯一的缺点是,当我在 Regex101.com 上比较速度时,这个正则表达式实际上比原来的慢了 15 倍。对于测试日志来说,这只会多出几毫秒,所以它们实际上是相当可比的。如果我在日志中看到我的结果受到垃圾文本的影响,我会记住这一点。谢谢你的帮助。
        猜你喜欢
        • 2015-12-09
        • 1970-01-01
        • 1970-01-01
        • 2021-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多