matching multiple regular expressions using join

Viewed 433

I have a dictionary who's keys are all precompiled regular expressions. I want to match a string to any of these regular expressions.

When researching I found that you can match multiple regular expressions by joining them with the join method. But when I do so, I get a Type error:

import re

regex1 = re.compile("regex1.*")
regex2 = re.compile("regex2\d")
re_dict = {regex1 : "stuff", regex2 : "otherstuff"}
match_multiple = "|".join(list(re_dict.keys()))
string = 'regex25'
if re.match(match_multiple, string):
    print("matched")

This gives:

Traceback (most recent call last):
   File "./a.py", line 7, in <module>
    match_multiple = "|".join(list(re_dict.keys()))
TypeError: sequence item 0: expected str instance, re.Pattern found
1 Answers

str.join works on strings, not re objects. Join then compile.

regex1 = "regex1.*"
regex2 = "regex2\d"
re_dict = {regex1 : "stuff", regex2 : "otherstuff"}
match_multiple = re.compile("|".join(re_dict))

note that dicts aren't ordered (unless you're running python 3.6) so if order of the expressions matter, your code may be incorrect

Also note the simplification from list(re_dict.keys()) to re_dict as iterating on a dictionary yields its keys. No need to call keys or convert to list explicitly.

(well, using a dictionary here is not really useful anyway. How to use the regex as key in the future?)

If you only have access to precompiled expressions, then "emulate" the regex or with any

if any(r.match(string) for r in re_dict):

any short-circuits, so it exits with True as soon as one regex matches.

Or rebuild the pattern by using the pattern regex attribute:

match_multiple = re.compile("|".join([r.pattern for r in re_dict]))
Related