用python的re-modu解析文件名

2024-10-01 13:30:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发视频播放器,它扫描用户的视频文件并尝试从文件名中识别它们。如果视频是电影,我想知道它的名称和视频的质量,如果它是一个电视节目,我想知道该节目的名称,季数,集数和视频的质量。在

我在google上搜索了一些示例文件名,并制作了一个简单的脚本来尝试获取信息,但我很难处理异常情况,例如,当有集的名称在质量之前,当文件有类似“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")

Tags: 视频lenif质量tvmovieelseprint
3条回答

如果使用重复冗长旗子。在

我明白了

[\d+]{3,4}

我认为这是误导。这不是说“至少有一个十进制数的三四次重复”?我想

^{pr2}$

很好。在

在开发正则表达式时,我从创建小模式开始:

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

希望有帮助。在

正如Josh提到的,+限定符不应该与{m,n}一起使用。+匹配一个或多个re,而{}贪婪地匹配m到n个重复。(参见:re syntax)。在

他还指出使用re.VERBOSE来帮助您的regex可读性。在

编辑:(感谢@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)

同样,您可以对电影部分执行以下操作:

^{pr2}$

这是输出:

---------- 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

[ae*6]表示一个字符。这意味着这个字符可以是a,或者是{},或者是{},或者是{}。
那么就不必写[ |.],顺便说一句,意思是“字符是, either |,或者{}”。在

我做了一些改进。如果你有问题,尽管问我。在

注意:像这样的部分:(?:[ .](\d{3}\d?p)|\Z).*?之后 必须强制惰性点.*?转到下一个点然后是720p如果有,不要停在第一个点并且考虑数字和p是可选的。
如果没有这样的720p,lazy dot会一直到字符串的末尾(\Z强迫它这样做),并声明它没有找到任何720p。在

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)

相关问题 更多 >