Incorporating regular expressions has been clunky. Let’s imagine that we need to search for a few regular expressions in some text and then perform task when a term is found. In code:
for pattern in [REGEX_1_PAT, REGEX_2_PAT, ...]: match = pattern.search(text) if match: do_something(match, text) break
Unfortunately, we can’t just use the match
because, if the pattern is not in text
, the result is None
. So, before using the match
, we need ensure that we have a valid match and not None
. These two lines (lines 2-3 above) are a bit of an eyesore, especially as one may have to include this pattern frequently. Why can’t we assign and do the if
check in a single line?
Well, Python 3.8 introduced the assignment expression (aka, the ‘walrus operator’ should one tilt ones head and imagine the smiling face of a certain aquatic mammal…). This allows a single line to both assign and check for existence. While there are many use cases, I have particularly enjoyed the improvements in using regular expressions. The below performs the same as above:
for pattern in [REGEX_1_PAT, REGEX_2_PAT, ...]: if match := pattern.search(text): do_something(match, text) break
This pattern is useful when we are looking only for a solitary case (e.g., with re.search
). The walrus operator is not required with a pattern I find myself reaching for more frequently: re.finditer
. With re.finditer
, we are looking for all instances of an expression and want to run do_something
every time we find a match.
for pattern in [REGEX_1_PAT, REGEX_2_PAT, ...]: for match in pattern.search(text): do_something(match, text)