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

Dav*_*vid 37 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
Run Code Online (Sandbox Code Playgroud)

如果要删除多个字符,则此操作无效.

Ale*_*inn 116

unicode中有数百个控制字符.如果要从Web或其他可能包含非ascii字符的源清理数据,则需要使用Python的unicodedata模块.该unicodedata.category(…)函数返回任何字符的unicode类别代码(例如,控制字符,空格,字母等).对于控制字符,类别始终以"C"开头.

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

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

unicode类别的示例:

>>> 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'
>>>
Run Code Online (Sandbox Code Playgroud)

  • Upvoting,因为这是unicode感知应用程序的唯一正确答案. (2认同)
  • 这应该标记为正确的答案 (2认同)
  • 这是一个非常可靠的删除不可打印字符的解决方案,谢谢! (2认同)

Sil*_*ost 25

您可以使用str.translate适当的地图,例如:

>>> mpa = dict.fromkeys(range(32))
>>> 'abc\02de'.translate(mpa)
'abcde'
Run Code Online (Sandbox Code Playgroud)

  • 我建议不要使用`map`作为变量名. (6认同)
  • @ user1476056:比你需要使用更新版本的Python.问题显然是标记为`python-3.x` (5认同)
  • 此代码无效.我一直得到`TypeError:期望一个字符缓冲区对象`错误.Python 2.6. (4认同)
  • 但请注意,这会破坏换行符. (3认同)

cmc*_*cmc 12

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

pip install regex

import regex as rx
def remove_control_characters(str):
    return rx.sub(r'\p{C}', '', 'my-string')
Run Code Online (Sandbox Code Playgroud)

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

  • 同意。与内置的 unicodedata 模块相比,`regex` 库将具有最新的 unicode 信息。 (2认同)

AXO*_*AXO 10

任何对匹配任何Unicode 控制字符的正则表达式字符类感兴趣的人都可以使用[\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
Run Code Online (Sandbox Code Playgroud)

所以要re使用以下方法删除控制字符:

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

  • 这个和第一个答案的区别是,这仅适用于`Cc`,而适用于`C *` (2认同)

Mar*_*ers 8

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

return ''.join(c for c in line if ord(c) >= 32)
Run Code Online (Sandbox Code Playgroud)

  • 至少比`str.translate`慢两倍 (2认同)
  • 澄清:你是对的'ord(u'\ U00020000')`会失败,至少在UCS2版本的Python上会失败,但在这种情况下使用`ord(c)`就好了,因为迭代字符串总是会产生字符< = 65535. (2认同)

Eri*_*got 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)
Run Code Online (Sandbox Code Playgroud)