Regex for URL Slug Validation
A clean URL slug is lowercase words separated by single hyphens: hello-world, post-123. The trick in this pattern is the (?:-[a-z0-9]+)* group — by requiring every hyphen to be followed by at least one character, it rejects leading hyphens, trailing hyphens, and doubles in one stroke, with no lookaheads needed.
/^[a-z0-9]+(?:-[a-z0-9]+)*$/How it works, token by token
| Token | Meaning |
|---|---|
| ^[a-z0-9]+ | the first word: one or more lowercase letters or digits — so no leading hyphen |
| (?:- | each following word starts with exactly one hyphen |
| [a-z0-9]+) | …followed by at least one character — so no -- and no trailing hyphen |
| *$ | zero or more of those words, then end of string |
What it matches
hello-worldpost-123aHello-World-hellohello--worldTry it live
One candidate per line — the m flag makes the ^ and $ anchors apply to each line. Edit anything; it runs in your browser.
Variations
^[a-z0-9]+(?:[-_][a-z0-9]+)*$also allow underscores as separators^[a-z0-9-]{1,80}$loose length-capped form — pair with trim/collapse logic in codeLanguage notes
- This validates a slug; to generate one from a title (lowercasing, stripping accents), use a slugify function — see the text-to-slug converter.
Frequently asked questions
How does this reject double hyphens without a lookahead?
Structure instead of assertion: the string is defined as word (-word)*, and since every word needs at least one character, two hyphens can never be adjacent, and the string can't start or end with one.
Should slugs allow uppercase?
No — URLs are case-sensitive on most servers, so Hello-World and hello-world would be different pages. Lowercasing at generation time avoids duplicate-content problems and broken links.
Building something custom? The regex tester gives you live match highlighting for any pattern.