-2

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)

6
  • The non-capturing groups are because you need a group to attach a quantifier (+) too, but without the cost of it being a normal capturing group. Commented Nov 7, 2023 at 16:49
  • ...but for your needs, you don't need any noncapturing-groups (or any groups at all). Commented Nov 7, 2023 at 16:50
  • Protip: use Regex101.com for help with regular-expressions. Commented Nov 7, 2023 at 16:51
  • I think you mean like this without matching digits right? ^[a-z]+(?:-[a-z]+)*$ regex101.com/r/a05kLh/1 Commented Nov 7, 2023 at 16:58
  • @Dai I can't get it to work without that non-capturing group. If I remove it, it no longer seems to check for consecutive hyphens. Commented Nov 7, 2023 at 16:59

2 Answers 2

0

This expression also answers the question:

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

It meets all the requirements I originally needed.

Sign up to request clarification or add additional context in comments.

Comments

-1

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

5 Comments

It doesn't seem to work, because it allows digits.
@KennethR.Jones Whoops, sorry. check now.
Almost, but it still validates "csh-a-rp-". That should fail, because there is a dash at the end.
Third-time lucky?
@KennethR.Jones What what says?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.