2009-06-27 3 views
3
私は

名前付きグループを持つPerl正規表現をPythonに変換するにはどうすればよいですか?

# Perl > v5.10 
re => '^(?:(?<name>.*?)[\/\s._-]*)?(?<openb>\[)?(?<season>\d{1,2})[x\/](?<episode>\d{1,2})(?:-(?:\k<season>x)?(?<endep>\d{1,2}))?(?(<openb>)\])(?:[\s._-]*(?<epname>[^\/]+?))?$', 

ファイル名を解析するためのPython 2.5.4正規表現に私はVideo::Filename Perlモジュールで見つかった以下のPerlの正規表現を変換しようとしています

私も名前のグループを使用したい、と私はPythonで知っています名前付きグループの正規表現の拡張は異なりますが、私は構文について100%確信していません。

これは私が試したものです:

# Python (not working) 
r = re.compile(r'^(?:(?P<name>.*?)[\/\s._-]*)?(?P<openb>\[)?(?P<season>\d{1,2})[x\/](?P<episode>\d{1,2})(?:-(?:\kP<season>x)?(?P<endep>\d{1,2}))?(?(P<openb>)\])(?:[\s._-]*(?P<epname>[^\/]+?))?$') 

エラーが私が取得:

raise error, v # invalid expression 
sre_constants.error: bad character in group name 

は、例えば、この1つは私が変換するために管理し、それが動作します。しかし、私は上記のものが正しいとは思えません。私はPythonでコンパイルエラーが発生します。

# Perl: 
re => '^(?:(?<name>.*?)[\/\s._-]+)?(?:s|se|season|series)[\s._-]?(?<season>\d{1,2})[x\/\s._-]*(?:e|ep|episode|[\/\s._-]+)[\s._-]?(?<episode>\d{1,2})(?:-?(?:(?:e|ep)[\s._]*)?(?<endep>\d{1,2}))?(?:[\s._]?(?:p|part)[\s._]?(?<part>\d+))?(?<subep>[a-z])?(?:[\/\s._-]*(?<epname>[^\/]+?))?$', 

# Python (working): 
r = re.compile(r'^(?:(?P<name>.*?)[\/\s._-]+)?(?:s|se|season|series)[\s._-]?(?P<season>\d{1,2})[x\/\s._-]*(?:e|ep|episode|[\/\s._-]+)[\s._-]?(?P<episode>\d{1,2})(?:-?(?:(?:e|ep)[\s._]*)?(?P<endep>\d{1,2}))?(?:[\s._]?(?:p|part)[\s._]?(?P<part>\d+))?(?P<subep>[a-z])?(?:[\/\s._-]*(?P<epname>[^\/]+?))?$') 

どこから探し始めるかわかりません。

答えて

6

翻訳に2つの問題があります。まず第一に、openbの2番目の言及は、その周りに余分な括弧を持ち、conditional expressionであり、名前付きの表現ではありません。

\k<season>backreferenceを翻訳していないとします。Pythonは(P=season)を使用して同じものを使用します。私のために、次のコンパイル:私があなただったら、これは何かである場合は、将来的に表現を理解しておくことができるように

r = re.compile(r'^(?:(?P<name>.*?)[\/\s._-]*)?(?P<openb>\[)?(?P<season>\d{1,2})[x\/](?P<episode>\d{1,2})(?:-(?:(?P=season)x)?(?P<endep>\d{1,2}))?(?(openb)\])(?:[\s._-]*(?P<epname>[^\/]+?))?$') 

は、私は複数行の上にこの式を分割し、豊富なドキュメントを追加するためにre.VERBOSEを使用したいですしかし、それは維持する必要があります。

(第2のopenbの参照が条件式であり、逆参照を適切に翻訳した後に編集される)。

+1

Hmm Perlでは\ は、以前に定義された名前付きグループへの逆参照を意味するので、その正規表現(この場合)は同じ正規表現で2回の名前を持つことになります。 –

+0

ああ、そうだ。その後、それを(?P = name)参照に変換する必要があると私は考える。更新中。 –

+0

まあ、perlreのマニュアルページには、名前付きパターンやそれらの後方参照はまったく言及されておらず、私は今は間に合いませんので、読者のための練習として残しておきます。 –

0

これらの正規表現は、(()?)、とにかく:-) ...

病気のねじれた心の産物であるPythonとPerlの両方の条件があり、それがあるべきようにperlの構文は、上記に見えますこれはPython構文と同じです。つまり、existsという名前のグループのtrueとして評価されます。

どこから探し始めますか?モジュールのドキュメントはここにある:

http://docs.python.org/library/re.html http://www.perl.com/doc/manual/html/pod/perlre.html

+0

誰かの正規表現を読むと、常に私の脳は傷つきます。たぶん私はPythonで書き直す方が良いでしょう。 –

+0

残念ながら、彼らはregex拡張を使用しています。これらの拡張は2つの実装間で異なりますので、そのまま動かない。私はここのどこかで両方の専門家が私にその違いを示すことができることを望んでいた。 –

2

私は問題の一部が見つかりましたが、正確に全部の周りに私の心をラップせずに間違っているかを把握することはできません。

r = re.compile(r'^(?:(?P<name>.*?)[\/\s._-]*)?(?P<openb>\[)?(?P<season>\d{1,2})[x\/](?P<episode>\d{1,2})(?:-(?:\kP<season>x)?(?P<endep>\d{1,2}))? 

(?(P<openb>)\]) // this part here causes the error message 

(?:[\s._-]*(?P<epname>[^\/]+?))?$') 

問題はPythonでグループ名は、有効なPythonの識別子(documentationを確認してください)でなければならないという事実であるように思われます。カッコが問題のようです。それらを削除すると、

(?(P<openb>)\]) //with parentheses 
(?P<openb>\]) //without parentheses 

redefinition of group name 'openb' as group 6; was group 2 
+0

ええ、私もそうだと思うが、Pythonは名前付きグループが(?P ...)であり、その構文が一致しないと考えているが、その場所に何を入れるべきかわからないからだと思う。 –

0

私は間違っているかもしれませんが、あなたが使用して後方参照を取得しようとしました:

(?:\k<season>x) 

は、Pythonでの構文\g<name>ありませんか?

関連する問題