preg_match to validate a URL slug

I hope this code is self-explanatory:

<?php

function test_username($username){
    if(preg_match('/^[a-z][-a-z0-9]*$/', $username)){
        echo "$username matches!\n";
    } else {
        echo "$username does not match!\n";
    }
}

test_username("user-n4me");
test_username("user+inv@lid")

But if not, the function test_username() test its argument against the pattern:

  • begins (^) ...
  • with one letter ([a-z]) ...
  • followed by any number of letters, numbers or hyphens ([-a-z0-9]*) ...
  • and doesn't have anything after that ($).

Better solution:

function is_slug($str) {
    return preg_match('/^[a-z0-9]+(-?[a-z0-9]+)*$/i', $str);
}

Tests:

  • fail: -user-name
  • fail: user--name
  • fail: username-
  • valid: user-name
  • valid: user123-name-321
  • valid: username
  • valid: USER123-name
  • valid: user-name-2

Enjoy!