从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.fromkeys
和map
来简洁地生成一个包含字典
{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中运行良好