用于匹配音乐和弦的正则表达式

时间:2012-06-27 14:54:44

标签: regex music-notation

我正在尝试编写一个函数来解析音乐和弦的字符串表示。

示例:C大调和弦 - > Cmaj (这是我要解析的内容)

为了说清楚,和弦由三个不同部分组成:

  • 音符(C,D,E,F,G,A)
  • 该笔记的意外事件(#,##,b,bb)
  • 和弦名称

对于那些精通音乐的人,我不是在考虑斜杠(故意)。

以下功能几乎正常。但是,它仍然不适用于以下情况:

  • “C#maj”#matches and should
  • “C#maj7”#匹配并且应该
  • “C#maj2”#算术,不应该

我想如果我可以让chords正则表达式部分被迫在正则表达式的末尾,那就行了。我已尝试在此字符串之前和之后使用$,但它不起作用。

有什么想法吗?感谢。

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

4 个答案:

答案 0 :(得分:2)

在以下行中将[]更改为()

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

否则您只是制作角色课程,因此[maj7|maj|min7|min|sus2]只匹配字母m

我猜你也想添加一个结尾锚$?我之前看到你遇到了问题,但这可能是因为上述问题。


另外,您是否希望(#|##|b|bb)成为可选项(例如,使用?(#|##|b|bb)?)?

答案 1 :(得分:2)

原谅JavaScript,但在纯粹的REGEX点上,这种模式似乎有效。你没有规定在和弦名称之后允许哪些数字,但我假设2只在'sus'之后被允许,7只在'min'和'maj'之后被允许。

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 :(得分:0)

在Wiseguy的回答基础上,我改进了你的正则表达式匹配。我必须在变量#之外添加accidentals,因为\b会导致匹配#。{/ p>

奖金:它甚至可以匹配Dsus9,D7等和弦。

原谅JavaScript,但这是我最终使用的代码:

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);

答案 3 :(得分:0)

我的声誉不足,无法评论Amit的帖子。

这就是我所使用的。重要的是要在“ m”之前检查“ maj”和“ min”,否则在诸如C#m的和弦上会出现错误的匹配。从技术上讲,这将允许使用C#9000之类的和弦,但我想在您的情况下这不会有太大问题。

[A-G](b|#)?(maj|min|m|M|\+|-|dim|aug)?[0-9]*(sus)?[0-9]*(\/[A-G](b|#)?)?