Python re.fullmatch accepts a value only when the pattern matches the entire string.
Python regular expressions: use fullmatch for a complete field contract
Operation contract
The receipt identifier boundary requires uppercase R, a hyphen and exactly four ASCII digits. It checks length before matching and prints acceptance for a valid field, rejection for prefixed text, a trailing newline and fullwidth digits. The pattern spells out the wire alphabet instead of assuming every character classified as a digit belongs in that format.
Failure and ownership boundary
A substring search answers whether a fragment exists, not whether the field is valid. Even fullmatch is not a complete application boundary: the matched identifier still needs authorization and existence checks before accessing a record. Avoid adding nested ambiguous repetitions to an attacker-controlled input path. Python input exercise: accept an explicit integer grammar and Python JSON validation: reject duplicate members and non-integer amounts solve different layers.
Working program
import re
RECEIPT_ID = re.compile(r"R-[0-9]{4}")
def valid_receipt_id(text):
return len(text) == 6 and RECEIPT_ID.fullmatch(text) is not None
for identifier in ["R-0041", "xR-0041", "R-0041\n", "R-0041"]:
print(valid_receipt_id(identifier))Output
True
False
False
FalseCosts and limits
This fixed-length pattern and six-character gate bound matching work. This cost statement does not apply to an arbitrary regular expression or an unbounded document.
Common Mistakes
- A matching identifier is not permission to read its record.
- Use an explicit wire alphabet rather than an unintended Unicode class.
Connected lessons
Python input exercise: accept an explicit integer grammar, Python JSON validation: reject duplicate members and non-integer amounts.
Follow the ownership and update boundary
Python urlsplit: parsing a URL does not authorize a request target.
