我有一个看起来像这样的文本文件:
Beethoven's Ode to Joy
667887654456655 667887654456544 556456764 5676545 1 667887654456544
Chrono Trigger - 600AD
(67 83456 654345 4 3456 7/4 8/6 5/3
6783456 654345 4 3456 7/4 8/6 8/6)
FF Prelude
1235 (1235 8 5321) 532
[678]3 678(3 6 3)876 31[7]
1235 (1235 8 5321) 532
[678]3 678(3 6 3)876 31[7]
[68]45 68(45 6 54)86 541
[7]2 567(2 567652)7652
1235 (1235 8 5321) 53~[1/3/5/8]
它是游戏中乐器演奏歌曲的音符列表,激战2。
我试图以比千行文本文件更好的格式创建一个应用程序来存储/读取这些笔记。我正在努力与正则表达式匹配这些歌曲标题和歌曲本身。 歌曲标题需要能够包含任何文本(以防万一)。 虽然歌曲的完整字符列表是:
0-9[](). ~/
由于
答案 0 :(得分:0)
您可以使用(?<Title>\S[^\n]+)\n
查找标题,这意味着匹配以非空格开头的行,然后匹配所有内容,直到找到\n
。
然后从那里查找代码(?<Code>\s{4}[\S\s]*?(?:(\r?\n){2}|$))
,这意味着在标题匹配所有内容之后有四个空格,直到找到双行换行符或文件末尾。
var matches = Regex.Matches(sampleText,
@"(?<Title>\S[^\n]+)\n(?<Code>\s{4}[\S\s]*?(?:(\r?\n){2}|$))");
然后您可以使用
迭代匹配foreach (Match match in matches)
{
var title = match.Groups["Title"].Value;
var code = match.Groups["Code"].Value;
// trim, etc...
}
见Regex Matching groups on MSDN。我在这个例子中使用named matched subexpression。
有关完整的正则表达式解释,请参阅我创建的Regex101/f5HaSx示例。
/(?<Title>\S[^\n]+)\n(?<Code>\s{4}[\S\s]*?(?:(\r?\n){2}|$))/g
(?<Title>\S[^\n]+)
\S
匹配任何非空格字符(等于[^\r\n\t\f ]
)[^\n]+
+
量词 - 在一次和无限次之间匹配,尽可能多次,根据需要回馈(贪婪)\n
匹配换行符(换行符)(ASCII 10)\n
匹配换行符(换行符)(ASCII 10)(?<Code>\s{4}[\S\s]*?(?:(\r?\n){2}|$))
\s{4}
匹配任何空格字符(等于[\r\n\t\f\v ]
){4}
量词 - 恰好匹配4次[\S\s]*?
*?
量词 - 零和无限次之间的匹配,尽可能少,根据需要扩展(懒惰)\S
匹配任何非空格字符(等于[^\r\n\t\f ]
)\s
匹配任何空格字符(等于[\r\n\t\f\v ]
)(?:(\r?\n){2}|$)
(\r?\n){2}
(\r?\n){2}
{2}
量词 - 准确匹配2次\r?
匹配回车符(ASCII 13)\n
匹配换行符(换行符)(ASCII 10)$
$
在字符串末尾断言位置,或者在字符串末尾的行终止符之前断言(如果有的话)