从Python中的string中删除特定的字符

我试图从Python中删除string中的特定字符。 这是我现在使用的代码。 不幸的是,它似乎没有做任何事情的string。

for char in line: if char in " ?.!/;:": line.replace(char,'') 

我如何正确地做到这一点?

Python中的string是不可变的 (不能改变)。 因此, line.replace(...)作用就是创build一个新的string,而不是改变旧string。 你需要重新绑定 (分配)它为了让这个variables采取新的值,删除这些字符。

而且,你这样做的方式会比较慢。 也有可能是有经验的pythonators有点混淆,他们会看到一个双重嵌套的结构,并认为一些更复杂的事情正在进行。

从Python 2.6和更新的Python 2.x版本*开始,您可以改为使用str.translate ,(但请阅读Python 3的差异):

 line = line.translate(None, '!@#$') 

或者使用re.sub正则expression式replace

 import re line = re.sub('[!@#$]', '', line) 

括号内的字符构成一个字符类 。 行中的任何字符都被replace为sub的第二个参数:一个空string。

在Python 3中,string是Unicode。 你将不得不翻译有点不同。 kevpie在对其中一个答案的评论中提到了这一点,并且在str.translate的文档中提到了这str.translate

当调用Unicodestring的translate方法时,不能传递我们上面使用的第二个参数。 你也不能传递None作为第一个参数,甚至不能传递来自string.maketrans的转换表。 相反,你传递一个字典作为唯一的参数。 这个字典将字符的序数值 (也就是调用ord的结果)映射到应该replace它们的字符的序数值,或者 – 对我们有用 – None意味着它们应该被删除。

所以要用Unicodestring来完成上面的跳舞,你可以调用类似的东西

 translation_table = dict.fromkeys(map(ord, '!@#$'), None) unicode_line = unicode_line.translate(translation_table) 

这里使用dict.fromkeysmap来简洁地生成一个包含字典

 {ord('!'): None, ord('@'): None, ...} 

更简单一些,正如另一个答案所说 ,创build字典到位:

 unicode_line = unicode_line.translate({ord(c): None for c in '!@#$'}) 

*为了与早期的Pythons兼容,你可以创build一个“null”转换表来代替None

 import string line = line.translate(string.maketrans('', ''), '!@#$') 

这里string.maketrans用于创build一个转换表 ,它只是一个string,包含序号为0到255的字符。

我是否错过了这一点,还是只是以下几点:

 >>> string = "ab1cd1ef" >>> string.replace("1","") 'abcdef' >>> 

把它放在一个循环中:

 >>> >>> a = "a!b@c#d$" >>> b = "!@#$" >>> for char in b: ... a = a.replace(char,"") ... >>> print a abcd >>> 
 >>> line = "abc#@!?efg12;:?" >>> ''.join( c for c in line if c not in '?:!/;' ) 'abc#@efg12' 
 line = line.translate(None, " ?.!/;:") 

提问者几乎已经有了。 像Python中的大多数事情一样,答案比您想象的要简单。

 >>> line = "HE?.LL!/;O:: " >>> for char in ' ?.!/;:': ... line = line.replace(char,'') ... >>> print line HELLO 

你不必做嵌套的if / for循环的事情,但你需要单独检查每个字符。

对于允许string中的某些字符的反向要求,您可以使用带补集运算符[^ABCabc]正则expression式。 例如,要删除除ASCII字母,数字和连字符之外的所有内容:

 >>> import string >>> import re >>> >>> phrase = ' There were "nine" (9) chick-peas in my pocket!!! ' >>> allow = string.letters + string.digits + '-' >>> re.sub('[^%s]' % allow, '', phrase) 'Therewerenine9chick-peasinmypocket' 

从python正则expression式文档 :

不在一个范围内的字符可以通过对该集合进行补充来匹配。 如果集合的第一个字符是'^' ,那么所有不在集合中的字符将被匹配。 例如, [^5]将匹配除“5”以外的任何字符, [^^]将匹配除'^'以外'^'任何字符。 如果不是集合中的第一个字符, ^没有特殊的含义。

 >>> s = 'a1b2c3' >>> ''.join(c for c in s if c not in '123') 'abc' 

string在Python中是不可变的。 replace方法在replace之后返回一个新的string。 尝试:

 for char in line: if char in " ?.!/;:": line = line.replace(char,'') 

用Python 3.5中的re.sub轻松实现

 >>> import re >>> line = 'Q: Do I write ;/.??? No!!!' >>> re.sub('\ |\?|\.|\!|\/|\;|\:', '', line) 'QDoIwriteNo' 

说明

在正则expression式(正则expression式)中, | 是一个逻辑或和\转义空格和特殊字符,可能是实际的正则expression式命令。 sub代表替代。

我很惊讶,还没有人推荐使用内置滤波器function。

  import operator import string # only for the example you could use a custom string s = "1212edjaq" 

假设我们想过滤出所有不是数字的东西。 使用内build的filter方法“…相当于生成器expression式(如果函数(item)的迭代项中的项目)”[ Python 3 Builtins: Filter ]

  sList = list(s) intsList = list(string.digits) obj = filter(lambda x: operator.contains(intsList, x), sList))) 

在Python 3中,这返回

  >> <filter object @ hex> 

要获得打印的string,

  nums = "".join(list(obj)) print(nums) >> "1212" 

我不确定在效率方面如何筛选排名,但在列表理解等方面知道如何使用是一件好事。

UPDATE

从逻辑上讲,因为filter的作品,你也可以使用列表理解,从我所读的,它应该是更有效的,因为lambdas是编程function世界的华尔街对冲基金经理。 另外一个好处是,这是一个不需要任何import的单线程。 例如,使用上面定义的相同string's'

  num = "".join([i for i in s if i.isdigit()]) 

而已。 返回将是原始string中所有字符的string。

如果您具有可接受/不可接受的字符的特定列表,则只需调整列表理解的“如果”部分即可。

  target_chars = "".join([i for i in s if i in some_list]) 

或者可选地,

  target_chars = "".join([i for i in s if i not in some_list]) 

这是我的Python 2/3兼容版本。 由于翻译API已经改变。

 def remove(str_, chars): """Removes each char in `chars` from `str_`. Args: str_: String to remove characters from chars: String of to-be removed characters Returns: A copy of str_ with `chars` removed Example: remove("What?!?: darn;", " ?.!:;") => 'Whatdarn' """ try: # Python2.x return str_.translate(None, chars) except TypeError: # Python 3.x table = {ord(char): None for char in chars} return str_.translate(table) 
 #!/usr/bin/python import re strs = "how^ much for{} the maple syrup? $20.99? That's[] ricidulous!!!" print strs nstr = re.sub(r'[?|$|.|!|a|b]',r' ',strs)#i have taken special character to remove but any #character can be added here print nstr nestr = re.sub(r'[^a-zA-Z0-9 ]',r'',nstr)#for removing special character print nestr 

这个怎么样:

 def text_cleanup(text): new = "" for i in text: if i not in " ?.!/;:": new += i return new 

下面的一个..用正则expression式概念..

 ipstring ="text with symbols!@#$^&*( ends here" opstring='' for i in ipstring: if i.isalnum()==1 or i==' ': opstring+=i pass print opstring 

您也可以使用函数来使用列表replace不同types的正则expression式或其他模式。 有了这个,你可以混合正则expression式,字符类和真正的基本文本模式。 当你需要replace很多像HTML一样的元素的时候,它是非常有用的。

注意:使用Python 3.x

 import re # Regular expression library def string_cleanup(x, notwanted): for item in notwanted: x = re.sub(item, '', x) return x line = "<title>My example: <strong>A text %very% $clean!!</strong></title>" print("Uncleaned: ", line) # Get rid of html elements html_elements = ["<title>", "</title>", "<strong>", "</strong>"] line = string_cleanup(line, html_elements) print("1st clean: ", line) # Get rid of special characters special_chars = ["[!@#$]", "%"] line = string_cleanup(line, special_chars) print("2nd clean: ", line) 

在函数string_cleanup中,它将stringx和您的列表不需要作为参数。 对于元素或模式列表中的每个项目,如果需要replace,则将完成。

输出:

 Uncleaned: <title>My example: <strong>A text %very% $clean!!</strong></title> 1st clean: My example: A text %very% $clean!! 2nd clean: My example: A text very clean 

我使用的方法可能不会有效,但它非常简单。 我可以一次删除不同位置的多个字符,使用切片和格式化。 这是一个例子:

 words = "things" removed = "%s%s" % (words[:3], words[-1:]) 

这将导致'删除'这个词'this'。

格式化对于在打印string中间打印variables非常有用。 它可以使用插入任何数据types,然后是variables的数据types; 所有的数据types都可以使用%s ,浮点数(又名小数)和整数可以使用%d

切片可以用于复杂的string控制。 当我把单词[:3] ,它允许我从string中select所有字符(冒号在数字之前,这将意味着'从开始到')到第四个字符(它包括第四个字符)。 原因3等于到第四个位置是因为Python从0开始。然后,当我把word [-1:] ,意味着最后第二个字符到最后(冒号在数字后面)。 把-1放在最后一个字符上,而不是第一个。 再一次,Python将从0开始。所以, 字[-1:]基本上意味着从第二个字符到string结束。

所以,通过在我要删除的angular色和将它们夹在一起之前的angular色切断字符,我可以删除不需要的字符。 把它想象成一根香肠。 在中间很脏,所以我想摆脱它。 我只是把我想要的两端切断,然后把它们放在一起,没有不需要的部分在中间。

如果我想删除多个连续字符,我只需在[](切片部分)中移动数字即可。 或者,如果我想从不同位置移除多个字符,我可以一次将多个切片夹在一起。

例子:

  words = "control" removed = "%s%s" % (words[:2], words[-2:]) 

删除等于“酷”。

 words = "impacts" removed = "%s%s%s" % (words[1], words[3:5], words[-1]) 

删除等于'macs'。

在这种情况下, [3:5]表示位置 3处的字符到位置 5处的字符(不包括最终位置处的字符)。

记住, Python从0开始计数 ,所以你也需要。

在Python 3.5中

例如,

 os.rename(file_name, file_name.translate({ord(c): None for c in '0123456789'})) 

从string中删除所有数字

即使下面的方法工作

 line = "a,b,c,d,e" alpha = list(line) while ',' in alpha: alpha.remove(',') finalString = ''.join(alpha) print(finalString) 

输出>> abcde

你可以使用set

  charlist = list(set(string.digits+string.ascii_uppercase) - set('10IO')) return ''.join([random.SystemRandom().choice(charlist) for _ in range(passlen)]) 

使用filter ,你只需要一行

 line = filter(lambda char: char not in " ?.!/;:", line) 

这将string视为一个迭代,并检查每个字符,如果lambda返回True

 >>> help(filter) Help on built-in function filter in module __builtin__: filter(...) filter(function or None, sequence) -> list, tuple, or string Return those items of sequence for which function(item) is true. If function is None, return the items that are true. If sequence is a tuple or string, return the same type, else return a list. 
 >>> # Character stripping >>> a = '?abcd1234!!' >>> t.lstrip('?') 'abcd1234!!' >>> t.strip('?!') 'abcd1234' 

试试这个:

 def rm_char(original_str, need2rm): ''' Remove charecters in "need2rm" from "original_str" ''' return original_str.translate(str.maketrans('','',need2rm)) 

这个方法在Python 3.5.2中运行良好