Reputation: 55
I have this regex I am supposed to create that accepts the following formats:
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
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-insensitiveg
stands for global, which will match all occurences, not just the firstconst 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
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
Reputation: 786091
You may use:
^(?:[a-zA-Z][a-zA-Z-][a-zA-Z]|[0-9]{4})$
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$
: EndUpvotes: 4
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})$
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