user12149354
user12149354

Reputation: 55

Regex for three letters and four numbers?

I have this regex I am supposed to create that accepts the following formats:

  1. Any 3 letters (case-insensitive, no other characters except for alphabetic characters)
  2. Any 2 letters with a dash in between (case-insensitive)
  3. Any 4 digits

This is what I have come up with so far: ^([a-zA-Z]([a-zA-Z]|-)[a-zA-Z])|[0-9]{4}$

The issue with this regex is that it accepts a combination of 4 letters as well, but I only want three consecutive letters. What do I need to change in my regex to accomplish this?

Upvotes: 1

Views: 4668

Answers (4)

AndreasPizsa
AndreasPizsa

Reputation: 1756

You can optimize your regex using character classes and modifiers to make your pattern more concise:

For example, in JavaScript Syntax, this would be

/\d{4}|[a-z]([a-z]|-)[a-z]/ig

  • \d is short for digits [0-9]
  • i stands for case-insensitive
  • g stands for global, which will match all occurences, not just the first

See example on Regex101

const pattern = /\d{4}|[a-z]([a-z]|-)[a-z]/ig

const test = (desc, str) => {
  const match = (str.match(pattern) || []).join(', ')
  console.log(desc, '\n', str, '→', match, match ? '✓' : '×')
}

test('Any 3 letters (case-insensitive, no other characters except for alphabetic characters)', 'fourhundredandfive')
test('Any 2 letters with a dash in between (case-insensitive)', 'no-one')
test('Any 4 digits', 'ab 1234567 ab')

Upvotes: 0

Barmar
Barmar

Reputation: 782508

Your first alternative that matches letters only has the ^ anchor, so it just checks that the input begins with 3 letters or 2 letters separated by hyphen.

Your second alternative only has $ anchor, so it just checks thatthe end of the input is 4 digits.

You need to put both anchors in both alternatives.

^([a-zA-Z]([a-zA-Z]|-)[a-zA-Z])$|^[0-9]{4}$

or put another group around everything except the anchors.

^(([a-zA-Z]([a-zA-Z]|-)[a-zA-Z])|[0-9]{4})$

Upvotes: 1

anubhava
anubhava

Reputation: 786091

You may use:

^(?:[a-zA-Z][a-zA-Z-][a-zA-Z]|[0-9]{4})$

RegEx Demo

RegEx Details:

  • ^: Start
  • (?:: Start non-capture group that match either of these 2 alternatives
    • [a-zA-Z][a-zA-Z-][a-zA-Z]: Match 3 letters or a letter-letter
    • |: OR
    • [0-9]{4}: Match 4 digits
  • ): End non-capture group
  • $: End

Upvotes: 4

Nick
Nick

Reputation: 147236

You need to enclose your alternations in a group so that the anchors apply to all of them:

^(([a-zA-Z][a-zA-Z-][a-zA-Z])|[0-9]{4})$

Demo on regex101

Note that you can simply include - in your second character class in the first alternation as [a-zA-Z-] is equivalent to ([a-zA-Z]|-).

Upvotes: 2

Related Questions