Hashtag Regex
Validates a social-media style hashtag: a leading # symbol followed by a letter and then any combination of letters, digits, and 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 |
| # | Literal hash symbol that begins every hashtag |
| [A-Za-z] | Requires the first character after # to be a letter, not a digit or underscore |
| [A-Za-z0-9_]* | Zero or more additional letters, digits, or underscores making up the rest of the tag |
| $ | Anchors the match to the end of the string |
Detailed Explanation
What it does
This pattern checks that a string is a single, complete hashtag: a # followed immediately by a letter, then any number of letters, digits, or underscores, with no spaces or punctuation.
Why it works
Splitting the body into a mandatory first letter (`[A-Za-z]`) and an optional tail (`[A-Za-z0-9_]*`) ensures a hashtag cannot be purely numeric or empty, matching the common social-platform convention that tags must start with a letter. Anchoring the whole string with `^` and `$` makes this pattern suitable for validating a single standalone tag rather than scanning free text for tags embedded in a sentence.
Common use cases
- Validating a single hashtag entered into a tag-input field before adding it to a post
- Checking that autocomplete suggestions for tags conform to platform naming rules
- Filtering a list of candidate tags to remove malformed or empty entries
- Server-side validation of tags submitted through an API before storage
Edge cases
- A bare # with nothing after it is correctly rejected as an empty tag
- Tags that are entirely numeric, like #123, are rejected since the first character after # must be a letter
- Unicode letters (e.g. accented characters or non-Latin scripts) are not matched by the basic A-Za-z class used here
- Hyphenated compound tags like #real-time are rejected since hyphens are not part of the allowed character set
Limitations
- Does not extract multiple hashtags from a larger block of free text; use a global, unanchored variant for that
- Does not support Unicode letters without switching to a Unicode-aware character class or the `u` flag with \p{L}
- Does not enforce a maximum tag length, which some platforms restrict for hashtags
- Does not distinguish between currently trending or platform-recognized tags versus arbitrary user-made ones
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 | |||
| Pass |
Language Variants
Production-ready examples in 12 languages.
const hashtagRegex = /^#[A-Za-z][A-Za-z0-9_]*$/;
console.log(hashtagRegex.test('#ThrowbackThursday')); // trueCommon Mistakes
Allowing the tag to start with a digit or underscore, which most platforms reject for hashtags
Fix: Require the first character after # to be a letter with `[A-Za-z]` before allowing digits or underscores in the rest of the tag
Using this anchored pattern to try to extract all hashtags from a paragraph of text
Fix: Drop the `^`/`$` anchors and add the `g` flag to scan for multiple `#word` occurrences within free text
Forgetting international users may type hashtags with accented or non-Latin letters
Fix: Swap the ASCII character classes for a Unicode-aware class like `\p{L}` combined with the `u` flag if global audiences are expected
Performance Notes
- The pattern has no nested or overlapping quantifiers, so it evaluates in linear time relative to input length
- Anchoring with `^` and `$` lets the engine reject clearly invalid strings (e.g. ones not starting with #) immediately
- When scanning large bodies of text for many tags, use a single global-flagged regex pass rather than looping this anchored version substring by substring
Browser Compatibility
| Engine | Supported | Notes |
|---|---|---|
| Chrome | Yes | — |
| Firefox | Yes | — |
| Safari | Yes | — |
| Edge | Yes | — |
| Node.js | Yes | — |