【发布时间】:2012-06-29 01:18:36
【问题描述】:
我正在尝试编写一个函数来解析音乐和弦的字符串表示。
示例:C 大调和弦 -> Cmaj(这是我要解析的)
为了清楚起见,和弦由三个不同的部分组成:
- 音符(C、D、E、F、G、A)
- 那个音符的变记号(#、##、b、bb)
- 和弦名称
对于那些精通音乐的人,我不考虑斜线和弦(故意)。
下面的功能几乎可以工作了。但是它仍然不适用于以下情况:
- "C#maj" # 匹配并且应该
- "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!");
}
}
【问题讨论】:
-
C#maj2和C#maj7之间的模式是相同的 (C#maj\d),因此区分它们并不是正则表达式的真正工作。我会抓取该模式的所有实例,然后使用更多的字符串模式进行验证。但是,您可以构建一个正则表达式,其中包含所有接受的数字作为文字。 -
我会制作包含所有可能和弦的静态集合。然后查看是否在 Collections 中找到了字符串表示形式。
-
"...对于那些精通音乐的人,我不考虑斜线和弦..." 只是为了记录:您忽略了 大多数 和弦,而不仅仅是斜线和弦.
-
是的,你是对的。我的意思是我无意为斜线和弦添加匹配,这意味着我必须更改正则表达式结构本身。我打算为
chords字符串添加更多和弦。为了清楚起见,我没有这样做。 -
别担心,我刚刚度过了每周一次的迂腐时刻 :) 和弦符号(以及其中的方言)有多种“方言”,您甚至可以或多或少地混合使用方言之间的部分。全世界的音乐家(至少有理论背景)都会理解任何组合,但几乎不可能想出一个简单的计算机匹配算法来做到这一点。 (我去过那里;))
标签: regex music-notation