2

ユーザーのビデオ ファイルをスキャンし、ファイル名から識別しようとするビデオ プレーヤーを開発しています。ビデオが映画の場合は、その名前とビデオの品質を取得したいと思います。テレビ番組の場合は、番組の名前、シーズン番号、エピソード番号、およびビデオの品質を取得したいと思います。

ファイル名の例をいくつかググって、情報を取得しようとする簡単なスクリプトを作成しましたが、品質の前にエピソードの名前がある場合、ファイルに「PROPER」のようなタグが付いている場合、またはユーザーが品質よりも「BluRay」のようなビデオのソースを置いています。

正規表現に詳しい人が助けてくれれば、本当にありがたいです。

ありがとう!

import re
names = [
    "The.Newsroom.2012.S02E06.720p.HDTV.x264-KILLERS.mkv",
    "Breaking.Bad.S05E10.Buried.HDTV.XviD-AFG.avi",
    "Breaking.Bad.S05E10.Buried.720p.HDTV.x264-AFG.mkv", #Incorrectly nonHD
    "Dexter.S08E08.HDTV.XviD-AFG.avi",
    "Dexter.S08E07.1080p.HDTV.x264-QCF.mkv",
    "Dexter S08E07 720p HDTV x264-QCF.mkv",
    "The.Great.Gatsby.2013.BluRay.1080p.DTS.x264-CHD.mkv", #Incorrectly nonHD
    "The Forbidden Girl 2013 BRRIP Xvid AC3-BHRG.avi",
    "Pain.&.Gain.2013.720p.BluRay.DD5.1.x264-HiDt.mkv",
    "Band.of.Brothers.S01E02.Day.of.Days.DVDRip.XviD-AC3-BAGS.avi",
    "Dexter.S08E06.PROPER.720p.HDTV.x264-IMMERSE.mkv", #Incorrectly nonHD
    "Dexter S08E06 PROPER 720p HDTV x264-IMMERSE.mkv" #Incorrectly nonHD
]
for name in names:
    tv = re.findall(r"(.*?)[ |.]S([\d+]{1,2})E([\d+]{1,2})[ |.]([\d+]{3,4}p|)", name) #FIXME: Get quality also after "PROPER/EPTITLE/.."
    if len(tv)>0:
        print("---------- TV ----------")
        print("Show: "+tv[0][0].replace(".", " "))
        print("Season: "+str(int(tv[0][1])))
        print("Episode: "+str(int(tv[0][2])))
        print("Quality: "+(tv[0][3] if len(tv[0][3])>0 else "nonHD"))
    else:
        movie = re.findall(r"(.*?[ |.][\d+]{4})[ |.]([\d+]{3,4}p|)", name) #FIXME: Get quality also after "BluRay/HDTV/HDDVD/.."
        if len(movie)>0:
            print("--------- MOVIE --------")
            print("Title: "+movie[0][0].replace(".", " "))
            print("Quality: "+(movie[0][1] if len(movie[0][1])>0 else "nonHD"))
        else:
            print("error")
4

4 に答える 4

2

Josh が述べたように、+修飾子は{m,n}. +re の 1 つ以上に一致しますが、{m,n}m から n までの反復に貪欲に一致します。(参照: re 構文)。

彼はまた、正規表現を読みやすくするためにre.VERBOSEを使用することを強調しました。

編集:(これを指摘してくれた@eyguemに感謝します)私は間違っているかもしれませんが、あなた[ |.]はスペースとピリオドを一致させようとしていますか?もしそうなら、 は必要なく、| などの特殊文字をエスケープするのは良い習慣かもしれません.。(つまり[ \.])。

シーズン/エピソードと品質の間の文字列がアルファベット、スペース、またはピリオドであることがわかっている場合は、次のようなものを使用できます (編集:「-」、「+」などのアルファベット以外の文字がある場合は、それらを文字セットに追加します):

    tv = re.findall(r"""(.*)          # Title
                        [ .]
                        S(\d{1,2})    # Season
                        E(\d{1,2})    # Episode
                        [ .a-zA-Z]*  # Space, period, or words like PROPER/Buried
                        (\d{3,4}p)?   # Quality
                    """, name, re.VERBOSE)

同様に、ムービー パーツに対して次の操作を実行できます。

movie = re.findall(r"""(.*?[ .]\d{4})  # Title including year
                       [ .a-zA-Z]*     # Space, period, or words
                       (\d{3,4}p)?      # Quality
                    """, name, re.VERBOSE)

これは出力です:

---------- TV ----------
Show: The Newsroom 2012
Season: 2
Episode: 6
Quality: 720p
---------- TV ----------
Show: Breaking Bad
Season: 5
Episode: 10
Quality: nonHD
---------- TV ----------
Show: Breaking Bad
Season: 5
Episode: 10
Quality: 720p
---------- TV ----------
Show: Dexter
Season: 8
Episode: 8
Quality: nonHD
---------- TV ----------
Show: Dexter
Season: 8
Episode: 7
Quality: 1080p
---------- TV ----------
Show: Dexter
Season: 8
Episode: 7
Quality: 720p
--------- MOVIE --------
Title: The Great Gatsby 2013
Quality: 1080p
--------- MOVIE --------
Title: The Forbidden Girl 2013
Quality: nonHD
--------- MOVIE --------
Title: Pain & Gain 2013
Quality: 720p
---------- TV ----------
Show: Band of Brothers
Season: 1
Episode: 2
Quality: nonHD
---------- TV ----------
Show: Dexter
Season: 8
Episode: 6
Quality: 720p
---------- TV ----------
Show: Dexter
Season: 8
Episode: 6
Quality: 720p
于 2013-08-20T19:12:28.560 に答える
1

[ae*6]1 文字を表します。これは、この文字が、 、 、または のいずれaかになることを意味します。では、ちなみに は「文字が 、 、 、またはのいずれかである」という意味で あると書く必要はありません。e*6
[ |.]|.

いくつかの改善を行いました。ご不明な点がございましたら、お気軽にお問い合わせください。

注意: このような部分: (?:[ .](\d{3}\d?p)|\Z) after.*? は、遅延ドットを強制的に.*?次のドットに移動させるために必要です。最初のドットで止まらないように、720p がある場合は720pが続きます。数字とpを考慮すると、オプションです。そのような720p
がない場合、レイジー ドットは文字列の最後まで進み (そうするように強制します)、 720pが見つからなかったことを宣言します。\Z

import re
names = [
    "The.Newsroom.2012.S02E06.720p.HDTV.x264-KILLERS.mkv",
    "Breaking.Bad.S05E10.Buried.HDTV.XviD-AFG.avi",
    "Trekking.Bad.S05E12.Buried.720p.HDTV.x264-AFG.mkv",
    "Dexter.S08E08.HDTV.XviD-AFG.avi",
    "Dexter.S08E07.1080p.HDTV.x264-QCF.mkv",
    "Dexter S08E07 720p HDTV x264-QCF.mkv",
    "The.Great.Gatsby.2013.BluRay.1080p.DTS.x264-CHD.mkv",
    "The Forbidden Girl 2013 BRRIP Xvid AC3-BHRG.avi",
    "Pain.&.Gain.2013.720p.BluRay.DD5.1.x264-HiDt.mkv",
    "Band.of.Brothers.S01E02.Day.of.Days.DVDRip.XviD-AC3-BAGS.avi",
    "Dexter.S08E06.PROPER.720p.HDTV.x264-IMMERSE.mkv",
    "Dexter S08E06 PROPER 720p HDTV x264-IMMERSE.mkv"
    ]

regtv = re.compile('(.+?)'
                   '[ .]S(\d\d?)E(\d\d?)'
                   '.*?'
                   '(?:[ .](\d{3}\d?p)|\Z)?')

regmovie = re.compile('(.*?[ .]\d{4})'
                      '.*?'
                      '(?:[ .](\d{3}\d?p)|\Z)?')

for name in names:
    tv = regtv.match(name)
    if tv:
        print("---------- TV ----------\n"
              "Show: %s\n"
              "Season: %s\n"
              "Episode: %s\n"
              "Quality: %s" %
              (tv.group(1).replace(".", " "),
               tv.group(2),
               tv.group(3),
               tv.group(4) if tv.group(4) else "nonHD")
              )
    else:
        movie = regmovie.match(name)
        if movie:
            print("--------- MOVIE --------\n"
                  "Title: %s\n"
                  "Quality: %s" %
                  (movie.group(1).replace(".", " "),
                   movie.group(2) if movie.group(2) else "nonHD")
                  )
        else:
            print("----- error for -----\n%s" % name)
于 2013-08-20T19:22:09.900 に答える
1

re.VERBOSE フラグを使用して正規表現が分割されていると役立つ場合があります。

そうですか

[\d+]{3,4}

これは誤解を招くと思います。これは「少なくとも小数点以下 1 桁を 3 回または 4 回繰り返す」という意味ではないでしょうか。おもう

\d{3,4}

結構です。

正規表現を開発するときは、小さなパターンを作成することから始めます。

episode_pattern = re.compile(r"S\d+E\d+", re.IGNORECASE)

それが役立つことを願っています。

于 2013-08-20T17:04:17.900 に答える