$re = '/^(?!.*\-\-)((main|next|staging|dev(elop)?|test(ing)?)$|^((feat(ure)?|(bug|hot)?fix|docs|wip|test(ing)?)\/(?!\-)([a-z0-9\-]{1,50}(?<!-)\/(?!\-))?[a-z0-9\-]{1,100}(?<!-))$|^release\/v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)$/m';
$str = 'main
next
staging
dev
develop
test
feat/lorem-ipsum
feature/dolorm
test/a-separate-branch-just-to-test-a-new-feature
bugfix/182-this-and-that
wip/work-in-progress-but-for-some-reason-someone-made-a-branch
fix/correct-branch
bugfix/517/alternative-bugfix-thingy
docs/reference/this-is-just-on-the-verge-of-being-way-too-long-but-it-is-still-acceptable-as-its-under-a-hundred
docs/reference/this-is-just-on-the-verge-of-being-way-too-long-but-it-is-still-acceptable-as-its-exactly-hundred-ch
hotfix/cannot-end-with-a-dash-
docs/no-consecutive-dashes
release/v1.0.0
release/1.0.0
release/v1.0.0-alpha.12
release/5123.1.5-some-meta-data
docs/gfdgdfs-
release
docs//no-consecutive-slashes
dev/invalid
wrong/im-wrong
docs/Bad-Casing
release/invalid_characters
docs/reference/this-one-is-obviously-just-way-too-long-to-make-sense-or-to-be-at-all-considered-by-the-expression-to-be-correct-as-its-very-clearly-not-correct-at-all
feat/cannot-end-with-a-slash/
docs/one/too/many/slashes';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for PHP, please visit: http://php.net/manual/en/ref.pcre.php