Regex match on all words?

J

Jakob Lithner

I would like to check that entered "words" are music chords.
I came up with this expression that I think will do for my purpose:
"^[A-H](#|b)?(m|sus)?[0-9]?$"

All chords are entered on a line.
Chords are separated by spaces or slash "/".

I am new to regex handling and have therefore this question:
Is it possible to check the complete line in one go and verify that every
entered word
matches the expression?
 
C

Colbert Zhou [MSFT]

J

Jakob Lithner

Thanks Colbert for your suggestion.
However I don't get your example to work.

My best approach right now is to split the line into "words" and then check
each word for the regex chord expression. Not elegant but it works.

/// <summary>
/// Checks if the line only contains music chords.
/// </summary>
public bool IsChords(string line)
{
var words = line.Split(" /".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries);
if (words.Length == 0)
return false;

var chordExpression =
"^[A-H][m|mi|maj|dim|°|sus|add|+|-|2|no3|3|4|5|6|7|9|11|13|Δ|∆]*$";
foreach (var word in words)
{
if (!Regex.IsMatch(word, chordExpression))
return false;
}
return true;
}

I can live with this but suggestions for improvements are welcome!
If possible it would be good to get rid of the split and looping that seems
unnecessary.

Another question:
My wife who is a music teacher made me adjust the previous expression as
there are chord variations that didn't fit into the first suggested pattern.
I then came up with the more general pattern used in the code above.
But to my irritation it also accepts wrong chords like "A14".
Can anyone explain that to me? Is it possible to avoid in some way?
My intention with the long OR sequence is to have any of the alternatives to
be repeated any number of time, but each alternative should match exactly. As
far as I see, it is not possible to combine the above alternatives and come
up with "14".
 
M

miher

Jakob Lithner said:
Thanks Colbert for your suggestion.
However I don't get your example to work.

My best approach right now is to split the line into "words" and then
check
each word for the regex chord expression. Not elegant but it works.

/// <summary>
/// Checks if the line only contains music chords.
/// </summary>
public bool IsChords(string line)
{
var words = line.Split(" /".ToCharArray(),
StringSplitOptions.RemoveEmptyEntries);
if (words.Length == 0)
return false;

var chordExpression =
"^[A-H][m|mi|maj|dim|°|sus|add|+|-|2|no3|3|4|5|6|7|9|11|13|Δ|∆]*$";
foreach (var word in words)
{
if (!Regex.IsMatch(word, chordExpression))
return false;
}
return true;
}

I can live with this but suggestions for improvements are welcome!
If possible it would be good to get rid of the split and looping that
seems
unnecessary.

Another question:
My wife who is a music teacher made me adjust the previous expression as
there are chord variations that didn't fit into the first suggested
pattern.
I then came up with the more general pattern used in the code above.
But to my irritation it also accepts wrong chords like "A14".
Can anyone explain that to me? Is it possible to avoid in some way?
My intention with the long OR sequence is to have any of the alternatives
to
be repeated any number of time, but each alternative should match exactly.
As
far as I see, it is not possible to combine the above alternatives and
come
up with "14".

Hi,

Try this :
string wordRegexp = ... // Your regexp here, without leading ^ and tailing
$
string lineRegexp = string.Format(@"^(({0})([\s|/])+)*({0})?$", wordRegexp);

I hope this will create the required regexp for You, just put Your "per
word" into it (dont forget to avoid ^ and $ since those sign input start and
end).

Hope You find this useful.
-Zsolt
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top