如何更好地解析随机跟踪列表

时间:2013-09-07 11:45:57

标签: python regex parsing text-parsing pyparsing

我有兴趣以各种格式解析列表,包含以下行:

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

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

1 个答案:

答案 0 :(得分:1)

最好的情况是,你正在处理一个context-sensitive grammar,它使你摆脱了regexp可以单独处理和解析的范围。

即使您的解析器是作为regexp和一堆启发式实现的,它仍然是一个解析器,解析的技术将是有价值的。有些语言有鸡蛋问题:我想称“艺术家以前称为艺术家,以前称为王子”是一位艺术家,而不是曲目标题,但直到我第二次看到它,我没有做出决定的背景。

要放大@JonClements注释,如果文件确实包含内部元数据,则有大量工具可以提取和处理该信息。即使内部元数据只增加了“平衡问题”是专辑标题的可能性,您也需要这些信息。

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