音乐和弦部分分裂正则表达式

时间:2012-06-27 15:18:21

标签: regex music-notation

这是对此问题的后续问题:Regex for matching a music Chord,我问过。

既然我有一个正则表达式来知道和弦的String表示是否有效(上一个问题),我怎样才能有效地得到和弦的三个不同部分(根音符意外事件和弦类型)成单独的变量?

我可以做简单的字符串操作,但我想在前面的代码构建并使用正则表达式会更容易,或者我错了吗?

以下是上述问题的更新代码:

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!");
    }
}

感谢。

3 个答案:

答案 0 :(得分:3)

用括号括起内容(具有特殊含义的情况除外)会创建capturing group或子模式。

您已将accidentalschords分组为此类子模式,但您需要将括号添加到notes以将其捕获为子模式。

String notes = "^([CDEFGAB])";
String accidentals = "(#|##|b|bb)?";
String chords = "(maj7|maj|min7|min|sus2)";

按照惯例,整个模式匹配的字符串是组0,然后每个子模式都被捕获为组1,组2,依此类推。

我不是Java人,但在阅读完文档后,看起来您会使用.group()访问子模式匹配:

String note = matcher.group(1);
String acci = matcher.group(2);
String chor = matcher.group(3);

编辑:

最初,我建议String accidentals = "((?:#|##|b|bb)?)";,因为我担心第二个子模式是可选的,如果不存在匹配则会导致组编号问题。但是,稍微测试表明,即使没有将其包裹在非捕获分组(?: )中,组2仍然存在但如果没有匹配则为空。 (无论如何,组2中的空字符串是期望的效果。)所以,似乎 ... = "(#|##|b|bb)?";可能就足够了。

答案 1 :(得分:2)

你已经完成了这项工作。只需添加一个捕获组,以便最终的正则表达式成为:

    ^([CDEFGAB])(#|##|b|bb)?(maj7|maj|min7|min|sus2)?$

你的音符,偶然和和弦将分别在第一,第二和第三次捕捉中。

答案 2 :(得分:2)

我喜欢接受的答案,但作为一名吉他手,我确实遇到了添加额外低音音符的和弦,例如G / D,A / D或D / F#。当然,您可能会遇到许多其他和弦名称,例如:5,6,min6,9,min9,sus4 ......等等。您可以考虑添加可能的弦乐和弦的数量,然后添加一些内容如果你有任何低音意外:

String chords =
"(maj|maj7|maj9|maj11|maj13|maj9#11|maj13#11|6|add9|maj7b5|maj7#5||min|m7|m9|m11|m13|
m6|madd9|m6add9|mmaj7|mmaj9|m7b5|m7#5|7|9|11|13|7sus4|7b5|7#5|7b9|7#9|7b5b9|7b5#9|
7#5b9|9#5|13#11|13b9|11b9|aug|dim|dim7|sus4|sus2|sus2sus4|-5|)";
String bass = "/([CDEFGAB])";

为了完成“字符串和弦”定义,您可能需要咨询chord dictionary。干杯!