Удаление управляющих символов из строки в Python - PullRequest
36 голосов
/ 01 декабря 2010

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

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 ]

103 голосов
/ 26 сентября 2013

В юникоде есть сотни контрольных символов. Если вы выполняете очистку данных из Интернета или из другого источника, который может содержать символы, отличные от ascii, вам потребуется модуль уникального Python . Функция unicodedata.category(…) возвращает код категории Unicode (например, управляющий символ, пробел, буква и т. Д.) Любого символа. Для управляющих символов категория всегда начинается с "C".

Этот фрагмент удаляет все управляющие символы из строки.

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

Примеры категорий юникода :

>>> 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'
>>>
24 голосов
/ 01 декабря 2010

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

>>> mpa = dict.fromkeys(range(32))
>>> 'abc\02de'.translate(mpa)
'abcde'
10 голосов
/ 09 сентября 2016

Любой, кто заинтересован в классе символов регулярного выражения, который соответствует любому 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'
7 голосов
/ 01 декабря 2010

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

return ''.join(c for c in line if ord(c) >= 32)
6 голосов
/ 01 декабря 2010

А для 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)
2 голосов
/ 16 января 2019

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

pip install regex

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

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

2 голосов
/ 01 декабря 2010
filter(string.printable[:-5].__contains__,line)
2 голосов
/ 01 декабря 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...