【发布时间】:2014-05-11 15:23:06
【问题描述】:
我正在处理这个问题。我有包含数十首歌曲的*.txt 文件。每首歌可能包含
- 姓名
- 有和弦的线
- 歌词台词
- 空白行
我正在编写 Python 脚本,它逐行读取文件。我需要识别带有和弦的线条。为此,我决定使用正则表达式,因为它看起来很有趣,但用于此类任务的强大工具。我是 regexp 的新手,我已经完成了 tutorial (我非常喜欢)。我写过这样的东西
\b ?\(?([AC-Hac-h]{1})(#|##|b|bb)?(is|mi|maj|sus)?\d?[ \n(/\(\))?]
我对此不太满意,因为它不能正常工作。问题之一是歌曲的语言使用了很多口音。第二个:和弦可能成对出现 - 例如C(D),h/e。你可以看看我的做法here。
注意 为了在最终脚本中获得更好的可读性,我会将正则表达式拆分为更多变量,然后将它们加在一起。
编辑
重读我的问题后,我想,我的目标可能不够明确。例如,我想要很多不同类型的和弦:
C, C#, Cis, c#, Cmaj, Cmi, Csus, C7, C#7, Db, Dbsus
有时也可能有(不超过两个)和弦相邻,例如:C7/D7, Cmi(a)。最好的解决方案是将这些“对”放在一个匹配C7/D7 而不是C7 和D7 中。我认为,有了这个附加条件,它可能会有点鲁棒,但如果它会变得不必要地困难,我可能会选择(我假设)更简单的版本(意思是:匹配 C7 和 D7 而不是 C7/D7)稍后单独处理。
【问题讨论】:
-
这个answer 可能会提供解决方案。
-
不要在整个文件中使用正则表达式并希望它起作用,而是使用与弦线与歌词线分开的先验知识将线分类为和弦或非和弦。然后,一旦将它们分开,标记化就很容易了。
-
@roippi 结构与上面的列表项并不完全相同。当我说“可能”时,这意味着可能有几行例如只有歌词。所以,我不知道哪条线是哪条线。我的不好,我没有强调这一点。
-
这并不能阻止您应用启发式方法来解决问题。你可以例如看看字母频率、字长、符号包含(带重音的行是歌词行)等。有很多方法可以做到。
-
@roippi 我已经考虑过了,但在我看来,这仍然是一种更困难的方法。我已经弄清楚如何更改编码,以便正则表达式正常工作。现在我将它写入文件时遇到问题(编码问题)。