1

我对解析各种格式的曲目列表感兴趣,其中包含以下行:

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 查看上一行/下一行
  • 使用单独的正则表达式来获取时间、曲目编号、艺术家、标题
  • 放弃并做一些没有意义的事情

我可以验证它是否已正确解析(在某种程度上)做一些事情,例如确保艺术家和标题都是不同的,曲目是有序的,时间是合理的,甚至可能检查艺术家/标题/标签确实存在。

4

1 回答 1

1

充其量,您处理的是上下文相关的语法,它使您脱离了正则表达式可以单独处理的领域并进入解析。

即使你的解析器被实现为一个正则表达式和一堆启发式,它仍然是一个解析器,解析技术将是有价值的。有些语言有一个先有鸡的问题:我想称“艺术家原名艺术家原名王子”为艺术家而不是曲目名称,但直到我第二次看到它,我没有做出该决定的背景。

为了放大@JonClements 的评论,如果文件确实包含内部元数据,那么有很多工具可以提取和操作该信息。即使内部元数据只会增加“平衡问题”是专辑标题的可能性,您也需要该信息。

尽可能多地窃取设计方法:寻找开源标签操纵器(例如 EasyTag),看看他们是如何做到的。在您学习的过程中,您可能会找到一个可以为您完成工作的工具。

于 2013-09-07T12:12:46.640 回答