Подтвердить что ты не робот

Удаление управляющих символов из строки в python

В настоящее время у меня есть следующий код

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

Это просто не работает, если удалено более одного символа.

4b9b3361

Ответ 1

Вы можете использовать str.translate с соответствующей картой, например, следующим образом:

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

Ответ 2

В юникоде есть сотни управляющих символов. Если вы дезинфицируете данные из Интернета или какой-либо другой источник, который может содержать символы, отличные от 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")

Примеры категорий 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'
>>>

Ответ 3

Ваша реализация неверна, потому что значение i неверно. Однако это не единственная проблема: она также многократно использует медленные операции с строкой, что означает, что она работает в O (n 2) вместо O (n). Вместо этого попробуйте:

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

Ответ 4

Любой, кто интересуется классом символов регулярного выражения, который соответствует любому управляющему символу 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

Таким образом, чтобы удалить управляющие символы, используя re просто используйте следующее:

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

Ответ 5

А для 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)

Ответ 6

Вы изменяете строку во время итерации по ней. Что-то вроде ''.join([x for x in line if ord(x) >= 32])

Ответ 7

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

Ответ 8

Это самый простой, самый полный и надежный способ, который я знаю. Это требует внешней зависимости, как бы то ни было. Я считаю, что оно того стоит для большинства проектов.

pip install regex

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

\p{C} - это свойство символа Unicode для управляющих символов, поэтому вы можете оставить его на усмотрение консорциума Unicode, какой из миллионов доступных символов Unicode должен рассматриваться как управляющий. Есть и другие чрезвычайно полезные свойства символов, которые я часто использую, например, \p {Z} для любых пробелов.