简体   繁体   中英

Regex: How can i get both teams of an event as cleanly as possible

I have been trying for a while now to successfully parse through bookmaker sites and retrieve markets/odds.

I have come to a point where I fetch the .text attribute of a Selenium web-element so I have something like this:

Edited to showcase more examples

BPZ vs Griffin - League of Legends - Challenger Korea
Sat 2/25   1511 BPZ 1.645         
10:30PM   1512 Griffin   2.250

Team Battle Comics vs RisingStar Gaming - League of Legends - Challenger Korea
Sat 2/25   1513 Team Battle Comics 5.800         
11:59PM   1514 RisingStar Gaming   1.133

Going In vs Hala Ares - Dota 2 - Prodota Cup
Sat 2/25   1529 Going In 1.667         
1:30PM   1530 Hala Ares   2.200

Unicorns of Love vs G2 Esports - League of Legends - Intel Extreme Masters
Sat 2/25   1545 Unicorns of Love 2.750         
11:15AM   1546 G2 Esports   1.444

What I am unable to do after literally hours of googling regex and reading the syntax, is to extract parts of this string as i need them. In the above string, if i could use regex to filter it into a dictionary that would look like this:

{'event':'BPZ vs Griffin - League of Legends',
 'outcome1':'BPZ',
 'outcome2':'Griffin',
 'outcome1odds':1.645,
 'outcome2odds':2.25,
 'date':'Sat 2/25',
 'time':'10:30PM'}

Then I would be extremely happy. I am fairly sure it is possible, but i am having too many difficulties wrapping my head around regex to achieve it. Any help and/or resources is much appreciated.

This pattern should do the trick:

(?P<event>(?P<outcome1>[^-]+?) vs (?P<outcome2>[^-]+) -.*?) -[^\b]*?(?P<date>(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun) \d+/\d+(?:/\d+)?)[^.]*(?P<outcome1odds>\d+\.\d+)\s+(?P<time>\d+:\d+[AP]M)[^.]*(?P<outcome2odds>\d+\.\d+)

It's very long, but in exchange you can use the .groupdict() function to directly get your desired result:

print(re.match(pattern, text).groupdict())

Breakdown:

(?P<event>          # in a named capture group, match...
    (?P<outcome1>   # outcome1, which is...
        [^-]+?      # all text up to...
    ) 
     vs             # a literal " vs " 
    (?P<outcome2>   # outcome2 is...
        [^-]+       # all text up to...
    )
     -              # the next literal " -"
    .*?             # still inside the "event" group, match until...
)
 -                  # a literal " -"
[^\b]*?             # skip forward to...
(?P<date>           # the date, which is...
    (?:Mon|Tue|Wed|Thu|Fri|Sat|Sun) # a weekday
     \d+/\d+(?:/\d+)?   # followed by digits separated with /
)
[^.]*               # skip worward to...
(?P<outcome1odds> 
    \d+\.\d+        # a floating point number
)
\s+
(?P<time>           # match the time, which is...
    \d+:\d+         # digits separated with :
    [AP]M           # followed by AM or PM
)
[^.]*               # skip to...
(?P<outcome2odds> 
    \d+\.\d+        # another floating point number
)

with this long regex, you can find your data in 8 Groups:

(.*-.*)\s-\s.*\n(\w{3})\s*(\d+\/\d+)\s*\d+\s*(\w+)\s*(\d+\.?\d*)\s*\n(\d+\:\d+\w\w)\s*\d+\s*(\w+)\s*(\d+\.?\d*)

Full match  0-104   `BPZ vs Griffin - League of Legends - Challenger Korea Sat 2/25 1511 BPZ 1.645
10:30PM 1512 Griffin 2.250`

Group 1.    n/a `BPZ vs Griffin - League of Legends`
Group 2.    n/a `Sat`
Group 3.    n/a `2/25`
Group 4.    n/a `BPZ`
Group 5.    n/a `1.645`
Group 6.    n/a `10:30PM`
Group 7.    n/a `Griffin`
Group 8.    n/a `2.250`

{'event':'$1',
 'outcome1':'$4',
 'outcome2':'$7',
 'outcome1odds':$5,
 'outcome2odds':$8,
 'date':'$2 $3',
 'time':'$6'}

https://regex101.com/r/2IdfnB/2

The solution using re.match() and match.groupdict() (gets all the named subgroups of the match) methods:

s = '''
BPZ vs Griffin - League of Legends - Challenger Korea
Sat 2/25   1511 BPZ 1.645
10:30PM   1512 Griffin   2.250
'''
p = r'^(?P<event>[\w ]+-[\w ]+)\s[\w\s-]+' \
    r'(?P<date>[A-Z]\w+ \d+\/\d{2})\s+\d+\s(?P<outcome1>[\w ]+)' \
    r'(?P<outcome1odds>\d+\.\d+)\s+(?P<time>\d+:\d+(AM|PM))\s+\d+\s' \
    r'(?P<outcome2>[\w ]+)(?P<outcome2odds>\d+\.\d+)'

matches = re.match(p, s.strip(), re.M)
result = {k:v.strip() for k,v in matches.groupdict().items()}
print(result)

The output:

{'time': '10:30PM', 'event': 'BPZ vs Griffin - League of Legends', 'outcome2odds': '2.250', 'date': 'Sat 2/25', 'outcome2': 'Griffin', 'outcome1': 'BPZ', 'outcome1odds': '1.645'}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM