【问题标题】:Music Chord part splitting Regex音乐和弦部分拆分正则表达式
【发布时间】:2012-06-29 02:02:33
【问题描述】:

这是这个问题的后续问题:Regex for matching a music Chord,由我提出。

现在我有一个正则表达式可以知道和弦的String 表示是否有效(上一个问题),我怎样才能有效地获得和弦的三个不同部分(根音accidentalschord type)转换成单独的变量?

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

这是来自上述问题的更新代码:

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

谢谢。

【问题讨论】:

    标签: regex music-notation


    【解决方案1】:

    我喜欢公认的答案,但作为一名吉他手,我确实会遇到添加了额外低音音符的和弦,例如 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。干杯!

    【讨论】:

      【解决方案2】:

      用括号括起来(除非有特殊含义)创建一个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)?"; 可能就足够了。

      【讨论】:

      • 我猜我是对的,认为有比字符串操作更好的方法。今天第二次感谢
      【解决方案3】:

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

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

      您的音符、变音记和和弦将分别出现在第一、第二和第三次捕捉中。

      【讨论】:

        猜你喜欢
        • 2012-06-29
        • 2012-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-05
        • 2013-08-11
        • 2021-12-04
        相关资源
        最近更新 更多