Python Identifier Regex
Validates that a string is a syntactically legal Python identifier: it must start with an ASCII letter or underscore, followed by any number of letters, digits, or underscores.
Regex Pattern
^[A-Za-z_][A-Za-z0-9_]*$Pattern Breakdown
Hover over a token to see what it does.
| Token | Meaning |
|---|---|
| ^ | Anchors the match to the start of the string |
| [A-Za-z_] | The identifier must begin with an uppercase letter, lowercase letter, or underscore |
| [A-Za-z0-9_]* | Zero or more letters, digits, or underscores make up the rest of the identifier |
| $ | Anchors the match to the end of the string, ensuring the whole string is a valid identifier |
Detailed Explanation
What it does
This pattern checks whether a string is shaped like a valid Python identifier: variable, function, class, or module name. It requires the first character to be a letter or underscore and every following character to be a letter, digit, or underscore, with no spaces, hyphens, or punctuation anywhere in the string.
Why it works
Python's grammar defines an identifier as starting with an ASCII letter or underscore and continuing with any mix of letters, digits, and underscores. The two character classes mirror that rule directly, and the ^/$ anchors force the entire input to satisfy it rather than just a substring, so something like foo-bar or 2fast is correctly rejected.
Common use cases
- Validating variable, function, or class names in a code generator or template engine
- Checking that a config key or CLI argument name can be used as a Python keyword argument
- Linting auto-generated column or field names before they are turned into Python attributes
- Sanitizing user-supplied strings before using them as dynamic attribute names via setattr
Edge cases
- A single underscore, _, is a fully valid identifier and matches
- Identifiers with trailing digits, like value2, are valid since digits are allowed anywhere after the first character
- Python 3 actually permits many Unicode letters in identifiers (e.g. café), which this ASCII-only pattern intentionally rejects
- Reserved words like class or def match this pattern structurally even though they cannot be used as identifiers in real Python code
Limitations
- Does not exclude Python keywords (class, def, return, etc.), which are structurally valid but semantically illegal identifiers
- Only covers the ASCII subset of legal identifier characters and ignores Python 3's Unicode identifier support
- Does not check identifier length limits or naming-convention style (snake_case vs camelCase)
Interactive Tester
Edit the pattern or text below — matching runs live in your browser.
Test Cases
Editable — add your own inputs to see if they pass.
| Input | Expected | Result | |
|---|---|---|---|
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass | |||
| Pass |
Language Variants
Production-ready examples in 12 languages.
const pythonIdentifierRegex = /^[A-Za-z_][A-Za-z0-9_]*$/;
console.log(pythonIdentifierRegex.test('my_variable_2')); // trueCommon Mistakes
Assuming this regex also rejects reserved keywords like class or import, since they look like normal identifiers
Fix: Cross-check the matched string against Python's keyword.kwlist (or the keyword module) in addition to the regex
Using \w+ alone (e.g. ^\w+$) and forgetting it allows an identifier to start with a digit like 123abc
Fix: Split the first character into its own [A-Za-z_] class separate from the repeating [A-Za-z0-9_]* tail
Expecting this ASCII-only pattern to accept Unicode identifiers such as café or变量, which real Python 3 allows
Fix: For full spec compliance use Python's own str.isidentifier() method instead of a hand-written regex
Performance Notes
- The two character classes are mutually exclusive in what they consume, so the engine runs in linear time with no catastrophic backtracking
- Anchoring with ^ and $ allows invalid strings to fail immediately on the first character
- Cheap enough to run on every token while parsing or linting large codebases without noticeable overhead
Browser Compatibility
| Engine | Supported | Notes |
|---|---|---|
| Chrome | Yes | — |
| Firefox | Yes | — |
| Safari | Yes | — |
| Edge | Yes | — |
| Node.js | Yes | — |