Batu Lab NotesPractical developer guides

Validate a whole local identifier with fullmatch

By Batu ยท English technical notes

Also published in our Blogger archive.

A local identifier rule is often clearer when the pattern describes one identifier and fullmatch() supplies the whole-string requirement. This example accepts an ASCII letter or underscore first, followed by ASCII letters, digits, or underscores. From five candidate values, only local_name and x2 are retained. 2fast fails because its first character is a digit; name-with-dash fails because a hyphen is not included; and name\n fails because the newline is extra input.

Pattern.fullmatch() returns a match only when the pattern covers the entire supplied string, so this avoids relying on ^ and $ anchors whose newline behavior can be surprising. The meaningful assertion checks the selected values, while the printed list makes the outcome deterministic. re and Pattern.fullmatch() are standard-library APIs; fullmatch() was added in Python 3.4. The raw string keeps the regular-expression backslashes literal in Python source. See the official re documentation and its character-class syntax.

This is a deliberately narrow, ASCII-oriented policy, not a universal definition of an identifier. Python source identifiers can contain many Unicode characters and have additional language rules; validate those with a parser or an appropriate language-specific rule when that is the real requirement. Assertions test these examples only; they do not establish that every possible input is handled correctly.

AI-assistance disclosure: this article was drafted with AI assistance and checked using a synthetic example.

import re

identifier = re.compile(r"[A-Za-z_][A-Za-z0-9_]*")
values = ["local_name", "x2", "2fast", "name-with-dash", "name\n"]

accepted = [value for value in values if identifier.fullmatch(value)]
assert accepted == ["local_name", "x2"]

print(accepted)
['local_name', 'x2']