A regex can look perfectly clever and still collect the wrong thing. `re.findall()` returns a list of all non-overlapping matches, so it is handy when the job is extraction: words matching a shape, suits in a hand, or ranks that repeat. The important question is not merely “Did it run?” but “What, exactly, went into the list?” section 2.6 section 4.15
Captured groups make that question more interesting. When a pattern contains a capturing group, `re.findall()` can return the captured portion rather than the entire text matched by the pattern. A pattern intended to recognize repeated ranks may therefore yield `['9']` for `AK992`: the list records the rank captured before its repetition, not the full repeated sequence. section 4.24
Treat a `findall()` result as evidence to inspect, not as a rubber stamp:
- Check the character class. `\w` may admit more than a supposedly lowercase word list intends. section 2.6
- Check boundaries and flags separately. Word boundaries may be useful, while `re.I` can be harmless yet unnecessary. section 2.6
- Check what a group extracts. A repeated capture can identify ranks occurring at least twice without distinguishing pairs from triples or four-of-a-kind. section 4.24
- Check the tests as skeptically as the pattern. A function and its comments can disagree about whether a poker hand is a flush. section 4.15
Repeated ranks: a useful answer that is not the whole answer
Consider `r"([^\u2660\u2665\u2666\u2663])\1+"`. The group captures a character that is not a suit, and `\1+` requires that character to repeat. Applied to `AK992`, it produces `['9']`; applied to `AA922`, it produces `['A', '2']`. This can find ranks appearing at least twice, but `AAA22` still produces `['A', '2']`, so it cannot tell a pair from a triple. Clever extraction is not yet a complete poker-hand classifier. section 4.24
>>> import re
>>> has_pair_regex = re.compile(
... r"([^\u2660\u2665\u2666\u2663])\1+",
... re.IGNORECASE | re.DOTALL)
>>> >>> has_pair_regex.findall("AK932")
[]
>>> has_pair_regex.findall("AK992")
['9']
>>> has_pair_regex.findall("AA922")
['A', '2']
>>> has_pair_regex.findall("AAA22")
['A', '2']
Inspect the interactive traces: they make the gap visible between matching a repeated sequence and returning the group that began it. section 4.24
`re.findall()` is often concise, but concision is not a reason to force regex into every task. Extracting suit symbols and comparing them can work, while splitting cards and indexing their suits may be more natural and readable. AI-generated regex code deserves the same treatment as hand-written code: keep the promising idea, then verify the pattern, returned values, and tests yourself. section 4.15 section 2.6

