/^/
EasyText Processing3 min read

URL Slug Regex

Validates a URL-friendly slug made of lowercase letters and digits, with single hyphens allowed only between word groups (no leading, trailing, or doubled hyphens).

#slug#url#text-processing#kebab-case#seo#string

Regex Pattern

^[a-z0-9]+(?:-[a-z0-9]+)*$

Pattern Breakdown

Hover over a token to see what it does.

^[a-z0-9]+(?:-[a-z0-9]+)*$
TokenMeaning
^Anchors the match to the start of the string
[a-z0-9]+One or more lowercase letters or digits forming the first word
(?:Start of a non-capturing group for repeated hyphen-separated words
-[a-z0-9]+A literal hyphen followed by one or more lowercase letters/digits
)*Closes the group and allows it to repeat zero or more times
$Anchors the match to the end of the string

Detailed Explanation

What it does

This pattern matches strings that follow the classic 'slug' convention used in blog and product URLs: lowercase alphanumeric words joined by single hyphens, such as my-blog-post-123. It rejects uppercase letters, spaces, underscores, and malformed hyphen placement.

Why it works

The pattern requires an initial run of lowercase letters/digits, then allows the non-capturing group (?:-[a-z0-9]+)* to repeat for each additional hyphen-joined word. Because each repetition of the group demands a hyphen immediately followed by at least one alphanumeric character, two consecutive hyphens or a hyphen at the start/end of the string can never satisfy the pattern, and the ^/$ anchors ensure the whole string is checked.

Common use cases

  • Validating slugs before saving them to a database or using them in a route
  • Auto-generating and then verifying SEO-friendly URLs from article titles
  • Enforcing consistent slug formatting in a CMS or static site generator
  • Sanitizing user-submitted permalink overrides

Edge cases

  • A single word with no hyphens, like hello, is valid since the repeating group is optional
  • Purely numeric slugs like 2026-07-10 are valid because digits are allowed alongside letters
  • Double hyphens (hello--world) are correctly rejected because the group requires an alphanumeric character right after each hyphen
  • Leading or trailing hyphens (-hello, hello-) are rejected since the string must start and end with an alphanumeric character

Limitations

  • Does not transliterate or normalize accented/Unicode characters — that must happen before validation
  • Does not enforce a maximum length, so extremely long slugs will still pass
  • Cannot detect semantically reserved slugs (e.g. 'admin' or 'api') — that needs an application-level check

Interactive Tester

Edit the pattern or text below — matching runs live in your browser.

hello-world my-blog-post-123 hello

Test Cases

Editable — add your own inputs to see if they pass.

InputExpectedResult
Pass
Pass
Pass
Pass
Pass
Pass
Pass
Pass

Language Variants

Production-ready examples in 12 languages.

const slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
console.log(slugRegex.test('my-blog-post-123')); // true

Common Mistakes

Using [a-z0-9-]+ without structure, which allows leading, trailing, and doubled hyphens like --hello--

Fix: Use the (?:-[a-z0-9]+)* structure so every hyphen is guaranteed to be followed by an alphanumeric character

Forgetting to lowercase and trim the source string before generating a slug

Fix: Normalize the input (toLowerCase, trim, replace spaces with hyphens) before running it through the validation regex

Not stripping accented characters, producing slugs like 'caf-au-lait' that lose information

Fix: Transliterate Unicode characters (e.g. e with an accent becomes e) before slugifying

Performance Notes

  • The pattern has no ambiguous overlap between the initial class and the repeated group, so it runs in linear time with no catastrophic backtracking risk
  • Anchors (^ and $) let the engine reject invalid strings immediately without scanning the whole input for a partial match
  • For slugifying large batches of titles, generate the slug first (lowercase, replace spaces) and use this regex only as a final validation gate

Browser Compatibility

EngineSupportedNotes
ChromeYes
FirefoxYes
SafariYes
EdgeYes
Node.jsYes