标准吉他 lyric/chord 包围的正则表达式

Regex for standard guitar lyric/chord bracketing

我正在尝试在 guitar/lyrics 格式的标准文本文档中的和弦周围添加方括号,以使它们与 OnSong 应用程序更兼容。我有规则,但不明白如何匹配所有可能的组合。规则是:

一些注意事项:这是一个帮助脚本...不需要完美。我现在手工做这个,所以偶尔的失误是可以的。我并不是要解析和弦的细节,只是将它们包裹在 [] 中。虽然标准布局是 1 排和弦,1 排歌词,但这不能指望,所以我知道有些场景偶尔会失败。

测试源(出于测试目的,和弦是随机的,以防任何音乐家加入糟糕的音乐):

Db    Dsus4/F#           A            Cbmin/C
A man can't be asked for that much to do
D/F#        G         A           D#/E
And I can't sweep you off of your feet

应该变成:

[Db]  [Dsus4/F#]         [A]          [Cbmin/C]
A man can't be asked for that much to do
[D/F#]      [G]       [A]         [D#/E]
And I can't sweep you off of your feet

我的第一次尝试使我接近:

([A-G]((?!\s).)*)

但是这也拾取了以这些字母开头的单词。我兜兜转转到现在才到:

\b([CDEFGAB](#|##|b|bb|sus|maj|min|aug)?\b)

当我尝试使用 [^\s+] 时,我得到的结果好坏参半,既获得了更多我想要的东西,也放弃了我需要的东西。我想我只是在我的头上。任何帮助将不胜感激,并且对其工作原理的任何解释都会更好。虽然我想要一个解决方案,但我也很想解释它为什么有效...

我有一些适用于您提供的案例的正则表达式,但不确定它如何适用于其他人。问题是一行可以以A开头,也可以在歌曲行中。我尝试使用负先行检查和弦是否后跟 space 和字母数字来解决它。如果有一个 space 和一个字母数字,我们不匹配这个和弦。由于和弦可以在 / 之后重复,我将模式加倍。

\b([CDEFGAB](?:b|bb)*(?:#|##|sus|maj|min|aug)*[\d\/]*(?:[CDEFGAB](?:b|bb)*(?:#|##|sus|maj|min|aug)*[\d\/]*)*)(?=\s|$)(?! \w)

看看the demo

这通过使用您的示例输入并实现您的所有 "super bonus points" 要求:

String output = input.replaceAll("(?m)(^| )([A-G](##?|bb?)?((sus|maj|min|aug|dim)\d?)?(/[A-G](##?|bb?)?)?)( (?!\w)|$)", "[]");

此代码将其转换为(作为带有嵌入式行费用的单个字符串):

Db    Dsus4/F#           A            Cbmin/C
A man can't be asked for that much to do
D/F#        G         A           D#/E
And I can't sweep you off of your feet

进入这个:

[Db]  [Dsus4/F#]         [A]          [Cbmin/C]
A man can't be asked for that much to do
[D/F#]      [G]       [A]         [D#/E]
And I can't sweep you off of your feet

代码在我检查过的示例中很好地执行了协议,Agreements simplesles 7th agreements with sharp or flat like C# 7

string strRegex = @"^[A-G]([5679bm#]([57])?|1[13]|6\/9|7[-#+b][59]|7?sus[24]|add[249]|aug|dim7?|m\/maj7|m1[13]|m[679]|m7?b5|maj1[13]|maj[79])?([\/][A-G]([5679bm#])?([57])?)?";

Regex myRegex = new Regex(strRegex, RegexOptions.None);
string strTargetString = @"A";
string strReplace = @"[[=10=]]";

return myRegex.Replace(strTargetString, strReplace);

我对之前答案的答案做了一些改进,以帮助解决我的问题。现在它忽略了一些 "chords likely" 当它在诗句的开头时(比如 A,E)。 这是我出来的:

(\(*[CDEFGAB](?:b|bb)*(?:#|##|sus|maj|min|aug|m|M|°|[0-9])*[\(]?[\d\/]*[\)]?(?:[CDEFGAB](?:b|bb)*(?:#|##|sus|maj|min|aug|m|M|°|[0-9])*[\d\/]*)*\)*)(?=[\s|$])(?! [a-z])

看看这个:

/([A-G](#|b)?)(\(?(M|maj|major|m|min|minor|dim|sus|dom|aug)?(\+|-|add)?\d*\)?)(\/([A-G](#|b)?))?/g

我从chord-transposer:

var XRegExp = require("xregexp");

// Chromatic scale starting from C using flats only.
var FLAT_SCALE = ["C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "Cb"];

// Chromatic scale starting from C using sharps only.
var SHARP_SCALE = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];

// Regex for recognizing chords
var ROOT_PATTERN = '(?<root>[A-G](#|b)?)';

var SUFFIX_PATTERN = '(?<suffix>\(?(M|maj|major|m|min|minor|dim|sus|dom|aug)?(\+|-|add)?\d*\)?)';

var BASS_PATTERN = '(\/(?<bass>[A-G](#|b)?))?';

var MINOR_PATTERN = '(m|min|minor)+';

var CHORD_REGEX = XRegExp("^" + ROOT_PATTERN + SUFFIX_PATTERN + BASS_PATTERN + "$");

然后

console.log(CHORD_REGEX); // will output regexp mentioned at the beginning of the answer

对我来说效果很好。