Удаление непечатаемых символов из строки в python


Я использую для запуска

$s =~ s/[^[:print:]]//g;

на Perl, чтобы избавиться от непечатаемых символов.

в Python нет классов регулярных выражений POSIX, и я не могу написать [:print:] имея это означает то, что я хочу. Я не знаю, как в Python определить, является ли символ печатным или нет.

что бы вы сделали?

EDIT: он также должен поддерживать символы Юникода. Строка.печатный способ с радостью лишит их выхода. брань.формат ascii.isprint вернется false для любого символа Юникода.

10 72

10 ответов:

итерация по строкам, к сожалению, довольно медленная в Python. Регулярные выражения на порядок быстрее, для такого рода вещей. Вы просто должны построить класс персонажа самостоятельно. Элемент unicodedata модуль весьма полезен для этого, особенно unicodedata.категория (). Смотрите База Данных Символов Юникода для описания категорий.

import unicodedata, re

all_chars = (unichr(i) for i in xrange(0x110000))
control_chars = ''.join(c for c in all_chars if unicodedata.category(c) == 'Cc')
# or equivalently and much more efficiently
control_chars = ''.join(map(unichr, range(0,32) + range(127,160)))

control_char_re = re.compile('[%s]' % re.escape(control_chars))

def remove_control_chars(s):
    return control_char_re.sub('', s)

насколько я знаю, самый питонический / эффективный метод будет:

import string

filtered_string = filter(lambda x: x in string.printable, myStr)

В Python 3,

def filter_nonprintable(text):
    import string
    # Get the difference of all ASCII characters from the set of printable characters
    nonprintable = set([chr(i) for i in range(128)]).difference(string.printable)
    # Use translate to remove all non-printable characters
    return text.translate({ord(character):None for character in nonprintable})

посмотреть это сообщение StackOverflow об удалении пунктуации как .translate () сравнивает с регулярным выражением & .заменить()

вы можете попробовать настроить фильтр с помощью unicodedata.category() функция:

printable = Set('Lu', 'Ll', ...)
def filter_non_printable(str):
  return ''.join(c for c in str if unicodedata.category(c) in printable)

посмотреть свойства символов базы данных Юникода в категории

эта функция использует список понимания и str.join, поэтому он работает в линейном времени вместо O (n^2):

from curses.ascii import isprint

def printable(input):
    return ''.join(char for char in input if isprint(char))

лучшее, что я придумал сейчас (благодаря питон-изерам выше)

def filter_non_printable(str):
  return ''.join([c for c in str if ord(c) > 31 or ord(c) == 9])

Это единственный способ, которым я узнал, что работает с символами/строками Юникода

есть варианты получше?

один ниже работает быстрее, чем другие выше. Взгляните

''.join([x if x in string.printable else '' for x in Str])

удалить 'пробел',

import re
t = """
\n\t<p>&nbsp;</p>\n\t<p>&nbsp;</p>\n\t<p>&nbsp;</p>\n\t<p>&nbsp;</p>\n\t<p>
"""
pat = re.compile(r'[\t\n]')
print(pat.sub("", t))

в Python нет классов регулярных выражений POSIX

есть при использовании regex библиотека:https://pypi.org/project/regex/

он хорошо поддерживается и поддерживает регулярное выражение Unicode, регулярное выражение Posix и многое другое. Использование (сигнатуры метода) -очень похоже на питона re.

из документации:

[[:alpha:]]; [[:^alpha:]]

поддерживаются классы символов POSIX. Эти обычно рассматриваются как альтернативная форма \p{...}.

(Я не связан, просто пользователь.)

еще один вариант в python 3:

re.sub(f'[^{re.escape(string.printable)}]', '', my_string)