Reputation: 4698
I am trying to validate user input that should be a valid note. In music, notes are letters A-G and can be either sharp(#) or flat(b). Notes don't have to be sharp or flat, they can be natural. Why is this regex not matching the # or b in any of the notes? Here is a regex101 demo.
([A-G]{1})(\#|b{1})?
Here is a list of all inputs that should match:
A
A#
Ab
B
Bb
C
C#
Cb
D
D#
Db
E
Eb
F
F#
Fb
G
G#
Gb
P.S. E# and B# don't exist in music, so I'll have to program that into my code.
Upvotes: 3
Views: 510
Reputation: 135772
Your regex:
([A-G]{1})(\#|b{1})?
Is correct.
To make your demo work, you need to remove the x
modifier, as it affects #
chars (it is a confusing modifier, actually). When you remove it, it shows your regex works (updated demo here).
About the x
modifier:
x
modifier: Ignore whitespaceThis flag tells the engine to ignore all whitespace and allow for comments in the regex. Comments are indicated by a starting "
#
"-character.
Now, if I may, you can simplify it by removing those {1}
, they are redundant (they default is match once already). Also, as noted by CSᵠ (see comment below), that #
doesn't need escaping and then \#|b
could become [#b]
:
([A-G])([#b])?
Of course, if you don't need to match the note (the first group) or the sharp/flat symbols (the second group) individually, you can remove parentheses as well.
Other than that, you can add the gm
modifiers to test multiple lines: DEMO here.
You don't have to program, you can not match E#
and B#
using regex only:
(?![EB]#)([A-G])([#b])?
This demo shows it working. The (?! ... )
is known as negative lookahead.
Upvotes: 3
Reputation: 174706
You must need to include anchors and also you have to enable multiline modifier m
.
^([A-G]{1})(\#|b{1})?$
or
^[A-G][#b]?$
Upvotes: 0