Python字符串清理

2024-03-28 10:22:07 发布

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

我正在用PyQT编写一个程序,它需要处理混乱的字符串并清理它们。可能的输入值变化很大。例如,我想以字符串为例:

"Seven_Pounds_(BDrip_1080p_ENG-ITA-GER)_Multisub_x264_bluray_.mkv",  
"The_Birds_1963_HDTV_XvidHD_720p-NPW.avi",  
"1892.XVID.AC3.HD.120_min.avi"  

把它们变成:
“七磅”
“小鸟”
“1892年”

我考虑过使用re来转义表达式,但是对于最后一个例子,这个方法似乎很可能失败。程序Media Gerbil使用google diff-match-patch算法来处理字符串清理。这似乎是一个更好的选择,但我不确定如何实现它。 在Python/PyQt中,有没有其他更有效的方法来清理字符串,或者regex或diff match补丁是最好的方法吗?在


Tags: 方法字符串程序matchdiffengpyqtx264
3条回答

从diff-match补丁的外观来看,match是最接近您所说的,在我看来,它可能不是最好的解决方案,因为match显然想要找到特定的模式(而不是regex规则)?在

我认为您可能需要定义一系列regex规则,例如将下划线视为单词之间的空格,以及任何可能表示标题结尾的非[a-zA-Z0-9_]+。您至少必须假设标题从字符串的开头开始,然后模式匹配,直到到达“非单词”字符为止。在

也许像这样?在

rx = re.compile(r'([a-zA-Z\d_]+[a-zA-Z\d])[_.]?')

但不幸的是,正如另一个答案中提到的,没有办法真正处理“1963年的鸟类”。我认为解决方案是一个组合,假设标题应该从哪里开始,可能在哪里结束,然后有一个公共标签列表可以去掉。在

编辑

也许一旦你已经缩小了你的潜在标题,你可以做一个谷歌差异匹配补丁,也许在一个API搜索互联网电影数据库,找到最接近真实标题的匹配项

实际上我曾经这样做过。。。你基本上遵循一系列步骤

  • 删除[]、()或{}中的任何内容
  • 删除文件扩展名
  • 现在在[\s.-\

在您的情况下,您将得到:

Seven Pounds Multisub x264 bluray
The Birds 1963 HDTV XvidHD 720p NPW
1892 XVID AC3 HD 120 min

现在你基本上保留了一个单词列表,在你看之前要从列表中清除掉。本例中显而易见的是x264、Multisub、bluray、HDTV、XvidHD、Xvid、HD、720p、1040p、AC3。请注意,您需要在这里进行不区分大小写的比较。在

请注意,当您浏览一个集合时,此列表将手动展开,这将给您留下

^{pr2}$

这大概和你能得到的半自动系统一样好。上面的一种方法会告诉你清除那些没有出现在前面的数字,但是我要指出的是,你会把《玩具总动员2》这样的东西搞砸。在

在我的例子中,我完成了上述处理,然后试图找出哪些目录模式与归档匹配。然后我有了一个基于诅咒的界面,允许我滚动并手动更正脚本的结论(包括重命名)。在

编辑:仔细想想,我的脚本实际上假设了一组的数字(以及之后的所有内容)可以安全地删除。不过,这些都是启发式的,你会遇到异常。添加该步骤会将最后一个示例标题更正为1892。在

根据您的例子:

import re

a="The_Birds_1963_HDTV_XvidHD_720p-NPW.avi"
b="Seven_Pounds_(BDrip_1080p_ENG-ITA-GER)_Multisub_x264_bluray_.mkv"
c="1892.XVID.AC3.HD.120_min.avi"

def cleanit(str):
    result = []
    l = re.split('[_.]',str)
    flag = 0
    if re.match('^[a-zA-z]+',l[0]):
        flag = 1
    elif re.match('^[0-9]+',l[0]):
        flag = 2

    if flag == 1:
        for x in l:
            if not re.match('^[a-zA-Z]+',x):
                break;
            result.append(x) 
        return " ".join(result)

    if flag == 2:
        for x in l:
            if not re.match('^[0-9]+',x):
                break;
            result.append(x) 
        return " ".join(result)

if __name__ == '__main__':
    print cleanit(a)
    print cleanit(b)
    print cleanit(c)

将打印:

^{pr2}$

相关问题 更多 >