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)