Regex patterns/Validation

URL slug

Lowercase words joined by single hyphens — no leading, trailing or doubled dashes.

/^[a-z0-9]+(?:-[a-z0-9]+)*$/
Open it in Rex

The problem

Check that a string is a clean URL slug before using it as a route.

How it reads

start[a-z0-9]repeatgroup-[a-z0-9]repeatrepeatskipend

Follow the line from left to right — every path you can trace is a string this pattern matches.

  1. ^[a-z0-9]+(?:-[a-z0-9…In order:
  2. ^The start of the text (or of a line with the m flag)
  3. [a-z0-9]+Any one of: "a" to "z" or "0" to "9", one or more times, as many as possible
  4. (?:-[a-z0-9]+)*Repeated any number of times, including none, as many as possible:
  5. (?:-[a-z0-9]+)Group (not captured):
  6. -[a-z0-9]+In order:
  7. -The character "-"
  8. [a-z0-9]+Any one of: "a" to "z" or "0" to "9", one or more times, as many as possible
  9. $The end of the text (or of a line with the m flag)

Matches

  • hello-world
  • my-first-post-2024
  • a

Does not match

  • -bad-slug
  • double--dash
  • Has-Capitals
  • trailing-

Where it bites

  • The obvious ^[a-z0-9-]+$ accepts ---, -x and x-, which is exactly what a slug must not be. Putting the hyphen inside a repeated group binds it to a following word.
  • Uppercase is rejected on purpose; slugify before validating rather than adding the i flag.
  • Non-ASCII letters are excluded, which matters if your URLs are not English.

More validation patterns