DoWhileFor
DoWhileFor

Reputation: 93

Why does java give different result for guitar chords

First, I try to extract all guitar chords from a simple text file using a regular expression. To me, it is working on https://regexr.com/ but it isn't working properly in java.

In this (simplified) task, a chord

I'm using Netbeans 8.2 IDE. I tried the following code snippet:

try (BufferedReader br = new BufferedReader(new FileReader(textFile))) {
    while ((line = br.readLine()) != null) {     
        Pattern p = Pattern.compile("\\b[CDEFGAB](([#b](?=\\s))|([#b]m7\\b)|([#b][m7]\\b)|(m7\\b)|([m7]\\b)|(\\b))");
        Matcher m = p.matcher(line);

        while (m.find()) {
            chords.add(m.group());
        }
    }
}

I get most chords but not the ones end with # and stand at the end of a line. I.e. I get only "F" (instead of "F#") here:

"C# F#\n"

It could be a good text for it: https://tabs.ultimate-guitar.com/tab/george_benson/nothings_gonna_change_my_love_for_you_chords_1080047

Upvotes: 3

Views: 222

Answers (2)

Leo Aso
Leo Aso

Reputation: 12473

You could do this with a much simpler regex:

Pattern.compile("\\b[A-G][b#]?m?7?(?!\\w)")

This should do exactly what you need. You can even expand it (Guitars have major and diminished 7th chords too, right?)

Pattern.compile("\\b[A-G][b#]?(7|m7?|M7|dim7?)?(?!\\w)")

Upvotes: 4

Marc G. Smith
Marc G. Smith

Reputation: 886

Your sharp expression is looking to match a space after it. The last chord in a line isn't matching that. You can either add a space to the line.

  Matcher m = p.matcher(line + " ");

or add an extra condition to your regular expression ([#b]$) and make sure the $ is set to match a new line vs the end of string using Pattern.MULTILINE.

   Pattern p = Pattern.compile("\\b[CDEFGAB](([#b]$)|([#b](?=\\s))|([#b]m7\\b)|([#b][m7]\\b)|(m7\\b)|([m7]\\b)|(\\b))", Pattern.MULTILINE);

Upvotes: 3

Related Questions