Doctor06
Doctor06

Reputation: 697

Regex pattern for underscore or hyphen but not both

I have a regular expression that is allowing a string to be standalone, separated by hyphen and underscore.

I need help so the string only takes hyphen or underscore, but not both.

This is what I have so far.

^([a-z][a-z0-9]*)([-_]{1}[a-z0-9]+)*$

foo             = passed
foo-bar         = passed
foo_bar         = passed
foo-bar-baz     = passed
foo_bar_baz     = passed
foo-bar_baz_qux = passed # but I don't want it to
foo_bar-baz-quz = passed # but I don't want it to

Upvotes: 4

Views: 1295

Answers (2)

Aaron Brock
Aaron Brock

Reputation: 4536

Here's a nice clean solution:

^([a-zA-Z-]+|[a-zA-Z_]+)$

Break it down!

  • ^ start at the beginning of the text
  • [a-zA-Z-]+ match anything a-z or A-Z or -
  • | OR operator
  • [a-zA-Z_]+ match anything a-z or A-Z or _
  • $ end at the end of the text

Here's an example on regexr!

Upvotes: 3

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626826

You may expand the pattern a bit and use a backreference to only match the same delimiter:

^[a-z][a-z0-9]*(?:([-_])[a-z0-9]+(?:\1[a-z0-9]+)*)?$

See the regex demo

Details:

  • ^ - start of string
  • [a-z][a-z0-9]* - a letter followed with 0+ lowercase letters or digits
  • (?:([-_])[a-z0-9]+(?:\1[a-z0-9]+)*)? - an optional sequence of:
    • ([-_]) - Capture group 1 matching either - or _
    • [a-z0-9]+ - 1+ lowercase letters or digits
    • (?:\1[a-z0-9]+)* - 0+ sequences of:
      • \1 - the same value as in Group 1
      • [a-z0-9]+ - 1 or more lowercase letters or digits
  • $ - end of string.

Upvotes: 4

Related Questions