Regular Expression for A-Z, Dash using Data Annotations

75 Views Asked by At

I need a regular expression for a URL-friendly slug, which can only contain lowercase letters and hyphens. It can't start or end with a hyphen and can't have more than one consecutive dash.

It will be used in a data annotation in C#:

[RegularExpression("", ErrorMessage = "Slug can only contain lowercase letters and dash; must not start or end with a dash; must not have more then 1 consecutive dash.")]

I tried the following expressions from this question.

/^[a-z0-9]+(?:-[a-z0-9]+)*$/
/^[a-z0-9]+(?:[_-][a-z0-9]+)*$/
  1. How can I modify the expressions to validate what I need?
  2. Can someone further explain how the non-capture group works in this case? I didn't understand the explanation I got from Google.

c-sharp (valid) c-sharp-code (valid) -csharp (invalid) csharp- (invalid) c--sharp (invalid) csharp9 (invalid) c_sharp (invalid)

2

There are 2 best solutions below

5
Dai On BEST ANSWER

Use:

^[a-z](?!.*--)[a-z\-]*[a-z]$

Demo: https://regex101.com/r/qXNO3y/3

Explanation:

^             # Anchor at start of string.
[a-z]         # The first character must be in the range [a-z].
(?!.*--)      # Assert that "--" does not appear anywhere from this point onwards.
[a-z\-]*      # Allow any subsequent chars to be in the range [a-z], or be '-' (while never matching "--" due to the assertion prior).
[a-z]         # The last character must be in the range [a-z]
$             # Anchor to the end of the string.

Usage:

static readonly Regex _slugRegex = new Regex( @"^[a-z](?!.*--)[a-z\-]*[a-z]$", RegexOptions.Compiled );

_slugRegex.IsMatch( "foo-bar"  ); // OK

_slugRegex.IsMatch( "foo--bar" ); // Fails
_slugRegex.IsMatch( "foo-bar-" ); // Fails
_slugRegex.IsMatch( "-foo-bar" ); // Fails
0
Kenneth R. Jones On

This expression also answers the question:

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

It meets all the requirements I originally needed.