我对解析各种格式的曲目列表感兴趣,其中包含以下行:
artist - title
artist-title
artist / title
artist - "title"
1. artist - title
0:00 - artist - tit le
05 artist - title 12:20
artist - title [record label]
这些是文本文件,通常包含一个跟踪列表,但也可能包含我不想解析的其他内容,因此理想情况下,正则表达式需要足够严格,不能包含不是跟踪列表的行,尽管这可能是平衡的问题。
我在以下正则表达式方面取得了一些成功:
simple = re.compile(r"""
^
(?P<time>\d?\d:\d\d)? # track time in 00:00 or 0:00
(
(?P<number>\d{1,2}) # track number as 0 01
[^\w] # not followed by word
)?
[-.)]? # possibly followed by something
"?
(?P<artist>[^"@#]+) # artist anything except "@#
"?
\s[-/\u2013]\s
"? # dash surrounded by spaces, possibly unicode
(?P<title>[^"@#]+?) # title, not greedy
"?
(?P<label>\[\w+\])? # label i.e. [something Records]
(//|&\#13;)? # remove some weird endings, i.e. ascii carriage return
$
""", re.VERBOSE)
但是,这有点可怕,我最近才开始学习正则表达式。像这样的行有问题:
an artist-a title # couldn't find ' - '
2 Croozin' - 2 Pumpin' # mistakes 2 as track number
05 artist - title 12:20 # doesn't work at all
在 2 Croozin' - 2 Pumpin' 的情况下,判断 2 不是曲目编号的唯一方法是考虑周围环境,即查看其他曲目。(我忘了提这个——这些曲目通常是曲目列表的一部分)
所以我的问题是,我一般如何改善这一点?我的一些想法是:
- 使用几个正则表达式,从非常具体的开始,然后继续使用不太具体的正则表达式,直到它被正确解析。
- 转储正则表达式并使用适当的解析器,例如 pyparsing 或 parsley,这可能能够更好地利用周围的上下文,但是我对解析一无所知
- 在多行正则表达式中使用lookahead/lookbehind 查看上一行/下一行
- 使用单独的正则表达式来获取时间、曲目编号、艺术家、标题
- 放弃并做一些没有意义的事情
我可以验证它是否已正确解析(在某种程度上)做一些事情,例如确保艺术家和标题都是不同的,曲目是有序的,时间是合理的,甚至可能检查艺术家/标题/标签确实存在。