如何使用列表中的正则表达式清理字符串

时间:2013-04-25 17:54:12

标签: python regex

在每种文件名中可以​​采用以下形式:

  • String1_Todelete_restofstring.txt
  • String2_Alsotoremove_restofstring.txt
  • String3_2013_restofstring.txt
  • String4_2011_restofstring.txt
  • String5_restofstring_tosuppress.txt

我想用 re.sub 定义一个函数,以删除列表中定义的所有关键字,(或字典无论如何),包括:

  

“Todelete”,2013,2011,“Alsotoremove”,“tosuppress”

这样,上面的例子(可能包括不同的日期)将成为:

  • String1_restofstring.txt
  • String2_restofstring.txt
  • String3_restofstring.txt
  • String4_restofstring.txt
  • String5_restofstring.txt

请告知

___编辑_

感谢您提供有用的答案。我发现Cobabunga实现紧凑在一个函数中实现。关于评论中的问题,没有坚持,因为我的意图是尽可能保持问题的通用性以允许所有类型的解决方案,甚至考虑我认为它也可以在正则表达式中实现的日期。

4 个答案:

答案 0 :(得分:2)

您可以构建一个正则表达式,其中包含您要删除的所有单词,如下所示:

import re

to_remove = ["Todelete", "2013", "2011", "Alsotoremove", "tosuppress"]
pattern = "|".join("_?" + re.escape(x) for x in to_remove)

names = ["String1_Todelete_restofstring.txt",
         "String2_Alsotoremove_restofstring.txt",
         "String3_2013_restofstring.txt",
         "String4_2011_restofstring.txt",
         "String5_restofstring_tosuppress.txt"]

names_replaced = [re.sub(pattern, "", x) for x in names]
print names_replaced

请注意,我在每个替换的单词之前都包含了一个可选的下划线('_'),因为如果您只在第一个示例中替换Todelete,那么您最终会得到{{1}而不是String1__restofstring.txt

对于您的具体示例,String1_restofstring.txt不是必需的,但如果您的单词包含正则表达式中具有特殊含义的任何字符,则在没有它的情况下会得到意外结果。

答案 1 :(得分:1)

这有效:

import re

st='''\
String1_Todelete_restofstring.txt
String2_Alsotoremove_restofstring.txt
String3_2013_restofstring.txt
String4_2011_restofstring.txt
String5_restofstring_tosuppress.txt'''

deletions=["Todelete", '2013','2011', "Alsotoremove","tosuppress"]

for line in st.splitlines():
    for deletion in deletions:
        if re.search('_'+deletion,line):
            line=re.sub('_'+deletion,'',line)
    print line  

修改

正如评论中所指出的,re.search是多余的。

此外,在特定情况下,str.replace 方式更快:

import re
import timeit 

st='''\
String1_Todelete_restofstring.txt
String2_Alsotoremove_restofstring.txt
String3_2013_restofstring.txt
String4_2011_restofstring.txt
String5_restofstring_tosuppress.txt'''

deletions=["Todelete", '2013','2011', "Alsotoremove","tosuppress"]


def rep():
    for line in st.splitlines():
        for deletion in deletions:
            line=line.replace('_'+deletion,'')


def reg():
    for line in st.splitlines():
        for deletion in deletions:
            line=re.sub('_'+deletion,'',line)            


print timeit.timeit('reg()', setup='from __main__ import reg', number=10000)     
print timeit.timeit('rep()', setup='from __main__ import rep', number=10000) 

在我的机器上,str.replace()的速度提高了约5倍。

答案 2 :(得分:1)

这可能比使用关键字扫描每个字符串的次数更高效。

import re

strings = """String1_Todelete_restofstring.txt
String2_Alsotoremove_restofstring.txt
String3_2013_restofstring.txt
String4_2011_restofstring.txt
String5_restofstring_tosuppress.txt""".split()

keywords = set(("Todelete", "2013","2011", "Alsotoremove","tosuppress"))

for s in strings:
    print re.sub("_[^_.]+", lambda m: "" if m.group(0)[1:] in keywords else m.group(0), s)

答案 3 :(得分:0)

给你一个想法(不长,因为我在手机上);

/(.*?)_.*?_(.*?)\.(\w{2,})/

group(1) + '_' + group(2) + '.' + group(3)