Regex to match Chord music

I am trying to write a function to parse a string representation of a musical chord.

Example: C main chord - > Cmaj (this is what I want to parse)

Just to understand, a chord consists of three different parts:

  • note (C, D, E, F, G, A)
  • randomness for this note (#, ##, b, bb)
  • chord name

For those who are versed in music, I do not consider slash chords (specifically).

The function below works. However, this still does not work for the following case:

  • "C # maj" # matches and should
  • "C # maj7" # matches and should
  • "C # maj2" # matches and should not

I believe that if I could get some of the regular expression chords to be at the end of the regular expression, I did the trick. I tried using $ both before and after this line, but that didn't work.

Any idea? Thanks.

 public static void regex(String chord) { String notes = "^[CDEFGAB]"; String accidentals = "[#|##|b|bb]"; String chords = "[maj7|maj|min7|min|sus2]"; String regex = notes + accidentals + chords; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(chord); System.out.println("regex is " + regex); if (matcher.find()) { int i = matcher.start(); int j = matcher.end(); System.out.println("i:" + i + " j:" + j); } else { System.out.println("no match!"); } } 
+8
regex music
source share
3 answers

Change [ and ] to ( and ) in the following lines:

 String accidentals = "(#|##|b|bb)"; String chords = "(maj7|maj|min7|min|sus2)"; 

Otherwise, you simply create character classes, so [maj7|maj|min7|min|sus2] just matches the letter m .

I assume you also want to add the final $ anchor? I see that you had problems with this before, but this is possible due to the above problem.


Also, maybe you want (#|##|b|bb) be optional (i.e. with ? (#|##|b|bb)? )?

+2
source share

Sorry JavaScript, but at a purely REGEX point, this pattern works. You did not indicate which numbers are allowed, followed by the names of the chords, but I suggested that 2 is only allowed after "gravy" and 7 only after "min" and "may."

 var chords = "C#maj7 C##maj Bbmaj7 Abmin2 Cbmin Dsus"; var valid_chords = chords.match(/\b[CDEFGAB](?:#{1,2}|b{1,2})?(?:maj7?|min7?|sus2?)\b/g); 
+2
source share

Based on Wiseguy's answer, I have improved regex matching. I had to add # outside the limits of the accidentals variable, since \b disables matching # .

Bonus : it even matches chords like Dsus9, D7, etc.

Sorry JavaScript, but this is the code I ended up in:

 var notes = "[CDEFGAB]", accidentals = "(b|bb)?", chords = "(m|maj7|maj|min7|min|sus)?", suspends = "(1|2|3|4|5|6|7|8|9)?", sharp = "(#)?", regex = new RegExp("\\b" + notes + accidentals + chords + suspends + "\\b" + sharp, "g"); var matched_chords = "A# is a chord, Bb is a chord. But H isn't".match(regex); console.log(matched_chords); 
0
source share

All Articles