Python issue with printing regex group from log file

Viewed 84

I am having difficulty printing two regex groups from a log file. I don't get any errors, I just don't get any results.

I'd like them to read as:

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

In this case I only want the account and High Score data from category2 printed. Im pretty new to Python, but i'm trying to learn more with practice. it seems my regex isnt returning any matches in python, but when i use this Regex101 tool, I am getting the two groups with my regex code. Maybe the issue is how I am printing the groups. Any help would be appreciated so that I can learn from my mistakes. :)

Here is my code:

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))

Example of Log file:

actual log file will stay around 400 - 600 lines, so i'm not to worried about loading it into memory.

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

Please let me know if you need any more information or context.

Thanks!

4 Answers

The below code can help you. I will give you a list of tuples containing email and score.

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))

Output

[('12345@email.com', '19290'), ('45678@email.com', '23625')]
for line in log:
    data = regex.findall(line)

What above code block is doing is applying your regex, on every single line, which will fail, as your regex spans across multiple lines. You will need to use your regex on the entire content.

Below code should work fine

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')

I think you complicated the Regex a little bit try this:

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'))

Using re.DOTALL, . will match \n so .*? will consume anything until the word High Score = is found.

You could try simplified version of your regex: Category2-{25}\n.+Account\s+(.+)[\s\S]+?High Score = (.+)

Account\s+(.+) - will match Account and one or emore whitespaces, so it will match until e-mail address and then will match everything until newline (so whole e-mail address) and store it inside capturing group.

Another modifiaction is [\s\S]+?, which matches EVERY character, one or more, non greedy, until High Score is matched. Then it matches and stores inside second capturing group the score (after equal sign).

Demo

Related