从python中的字符串中删除控制字符

时间:2010-12-01 13:25:53

标签: python string python-3.x

我目前有以下代码

def removeControlCharacters(line):
    i = 0
    for c in line:
        if (c < chr(32)):
            line = line[:i - 1] + line[i+1:]
            i += 1
    return line

如果要删除多个字符,则此功能无效。

8 个答案:

答案 0 :(得分:100)

unicode中有数百个控制字符。如果要从Web或其他可能包含非ascii字符的源清理数据,则需要使用Python unicodedata moduleunicodedata.category(…)函数返回任何字符的unicode category code(例如,控制字符,空格,字母等)。对于控制字符,类别始终以&#34; C&#34;。

开头

此代码段会从字符串中删除所有控制字符。

import unicodedata
def remove_control_characters(s):
    return "".join(ch for ch in s if unicodedata.category(ch)[0]!="C")

unicode categories的例子:

>>> from unicodedata import category
>>> category('\r')      # carriage return --> Cc : control character
'Cc'
>>> category('\0')      # null character ---> Cc : control character
'Cc'
>>> category('\t')      # tab --------------> Cc : control character
'Cc'
>>> category(' ')       # space ------------> Zs : separator, space
'Zs'
>>> category(u'\u200A') # hair space -------> Zs : separator, space
'Zs'
>>> category(u'\u200b') # zero width space -> Cf : control character, formatting
'Cf'
>>> category('A')       # letter "A" -------> Lu : letter, uppercase
'Lu'
>>> category(u'\u4e21') # 両 ---------------> Lo : letter, other
'Lo'
>>> category(',')       # comma  -----------> Po : punctuation
'Po'
>>>

答案 1 :(得分:24)

您可以将str.translate与相应的地图一起使用,例如:

>>> mpa = dict.fromkeys(range(32))
>>> 'abc\02de'.translate(mpa)
'abcde'

答案 2 :(得分:10)

任何对匹配任何Unicode control character的正则表达式字符集感兴趣的人都可以使用[\x00-\x1f\x7f-\x9f]

你可以这样测试:

>>> import unicodedata, re, sys
>>> all_chars = [chr(i) for i in range(sys.maxunicode)]
>>> control_chars = ''.join(c for c in all_chars if unicodedata.category(c) == 'Cc')
>>> expanded_class = ''.join(c for c in all_chars if re.match(r'[\x00-\x1f\x7f-\x9f]', c))
>>> control_chars == expanded_class
True

所以要使用re删除控制字符,只需使用以下内容:

>>> re.sub(r'[\x00-\x1f\x7f-\x9f]', '', 'abc\02de')
'abcde'

答案 3 :(得分:7)

您的实施错误,因为i的值不正确。然而,这不是唯一的问题:它也反复使用慢速字符串操作,这意味着它在O(n 2 )而不是O(n)中运行。试试这个:

return ''.join(c for c in line if ord(c) >= 32)

答案 4 :(得分:6)

对于Python 2,使用内置translate

import string
all_bytes = string.maketrans('', '')  # String of 256 characters with (byte) value 0 to 255

line.translate(all_bytes, all_bytes[:32])  # All bytes < 32 are deleted (the second argument lists the bytes to delete)

答案 5 :(得分:2)

在迭代过程中修改该行。像''.join([x for x in line if ord(x) >= 32])

这样的东西

答案 6 :(得分:2)

filter(string.printable[:-5].__contains__,line)

答案 7 :(得分:2)

这是我所知道的最简单,最完整,最可靠的方法。但是,它确实需要外部依赖。我认为对于大多数项目来说都是值得的。

pip install regex

import regex as re
def remove_control_characters(str):
    return re.sub(r'\p{C}', '', 'my-string')

\p{C}是控制字符的unicode character property,因此您可以将它留给unicode联盟,应将数百万个unicode字符中的一个视为控制字符。我还经常使用其他非常有用的字符属性,例如\p{Z}用于任何类型的空格。