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"
我考虑过用正则表达式来处理这些字符串,但我觉得这种方法在处理最后一个例子时可能会失败。程序Media Gerbil使用了google diff-match-patch算法来进行字符串清理。这似乎是个更好的选择,但我不太确定怎么实现它。
有没有其他更有效的方法可以在Python/PyQt中清理字符串,还是说正则表达式或者diff-match-patch是最好的选择呢?
5 个回答
其实我之前也做过这个...你基本上需要按照一系列步骤来操作。
- 先去掉方括号 []、圆括号 () 或大括号 {} 里的内容。
- 然后去掉文件的扩展名。
- 接下来用空格、点、短横线和下划线来分割字符串。
在你的情况下,你会得到:
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。记得这里要不区分大小写地比较。
注意,这个清单会随着你处理的内容而手动增加,这样你就会得到:
Seven Pounds
The Birds 1963
1892 120 min
这大概就是你能得到的半自动化系统的效果了。上面的方法会告诉你去掉那些不在开头的数字,但我想说这样会搞乱像“玩具总动员2”这样的标题。
在我的情况下,我做了上述处理,然后试着找出哪些目录模式适合归档。接着我用一个基于 curses 的界面,让我可以滚动浏览并手动修正脚本的结论(包括重命名)。
补充一下:再想想,我的脚本其实假设可以安全地去掉第二组数字(以及之后的所有内容)。不过这些都是经验法则,你肯定会遇到例外情况。如果加上这一步,就能把最后一个例子的标题改成 1892
。
从diff-match-patch的功能来看,match这个部分最接近你说的内容,但我觉得这可能不是最好的解决方案,因为match似乎是想找特定的模式(而不是正则表达式的规则)?
我觉得你可能需要定义一系列的正则表达式规则,比如把下划线当作单词之间的空格,任何非[a-zA-Z0-9_]+的字符可能表示标题的结束。你至少得假设你的标题是从字符串的开头开始的,然后匹配模式直到遇到一个“非单词”字符。
也许可以这样做?
rx = re.compile(r'([a-zA-Z\d_]+[a-zA-Z\d])[_.]?')
但不幸的是,正如其他回答中提到的,确实没有办法处理像“鸟类 1963”这样的标题。我认为解决方案是结合假设标题应该从哪里开始和可能结束,以及有一个常见标签的列表来去掉一些不必要的部分。
编辑 - 想到了更多的信息
也许当你尽可能缩小潜在标题的范围后,你可以再用google的diff-match-patch去对比一下imdb.com的API搜索,找到最接近真实标题的匹配。
根据你的例子:
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)
将会输出:
kent$ python cleanit.py
The Birds
Seven Pounds
1892