次のような行を含む、さまざまな形式のトラックリストを解析することに興味があります。
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]
これらは通常 1 つのトラックリストを含むテキスト ファイルですが、解析したくない他のものも含まれる可能性があるため、正規表現は理想的にはトラックリストではない行を含めないように十分に厳密である必要があります。バランスの問題。
次の正規表現である程度成功しています:
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 やパセリなどの適切なパーサーを使用します。これにより、周囲のコンテキストをより有効に活用できる可能性がありますが、解析についてはまったく知りません
- 複数行の正規表現で先読み/後読みを使用して、前/次の行を確認します
- 別の正規表現を使用して、時間、トラック番号、アーティスト、タイトルを取得します
- あきらめて、もっと無意味なことをする
アーティストとタイトルがすべて異なること、トラックが正しいこと、時間が適切であること、アーティスト/タイトル/レーベルが実際に存在することを確認することなどを行って、(ある程度) 適切に解析されたことを検証できます。