Backreferences match 'the same thing again', which no character class or quantifier can express.
A backreference in the pattern itself matches exactly the text a group captured earlier in the same match. (\w+) \1 finds a doubled word like the the. Named versions are (?P=name) in Python and \k<name> in PCRE, JavaScript, Java and .NET.
Common uses:
- Repeated words in prose:
\b(\w+)\s+\1\bwith the ignore-case flag. - Matching quotes:
(["'])(.*?)\1accepts"x"and'x'but not"x'. - Paired simple delimiters:
<(\w+)>.*?</\1>for non-nested tags. - Repeated characters:
(.)\1{2,}finds any character repeated three or more times.
Things to know:
- A backreference matches the text, not the pattern:
(\d)\1matches55, not56. - If the group didn't participate, Python fails the backreference, while JavaScript lets it match the empty string.
- Backreferences take regexes beyond regular languages. They make matching NP-hard in general, which is why RE2, Go and Rust leave them out and why they can be slow in grep.
- Don't confuse them with replacement references:
\1in the replacement string ofre.subis a different (simpler) mechanism.
Example
import re
text = "This is the the test, and and it works"
print(re.findall(r"\b(\w+)\s+\1\b", text)) # ['the', 'and']
print(re.findall(r'(["\'])(.*?)\1', ' "a" \'b\' "c\' ')) # [('"', 'a'), ("'", 'b')]
print(bool(re.fullmatch(r"<(\w+)>.*?</\1>", "<b>bold</b>"))) # True
print(bool(re.fullmatch(r"<(\w+)>.*?</\1>", "<b>bold</i>"))) # False
print(re.findall(r"((.)\2{2,})", "aaxyyyyz111")) # [('yyyy', 'y'), ('111', '1')]
print(bool(re.fullmatch(r"(?P<d>\d)(?P=d)", "55"))) # TrueRemember
- \1 inside the pattern matches the same text group 1 captured
- Named form: (?P=name) in Python, \k<name> elsewhere
- Backreferences are unsupported in RE2, Go and Rust and can be slow
Watch out for
- Expecting (\d)\1 to match any two digits; it matches only a repeated digit.