Pelar caracteres no imprimibles de una cadena en python
string non-printable (8)
Yo uso para correr
$s =~ s/[^[:print:]]//g;
en Perl para deshacerse de los personajes no imprimibles.
En Python no hay clases de expresiones regulares POSIX, y no puedo escribir [: imprimir:] que signifique lo que quiero. No sé de ninguna manera en Python para detectar si un personaje es imprimible o no.
¿Qué harías?
EDITAR: También debe admitir caracteres Unicode. El modo string.printable los eliminará alegremente de la salida. curses.ascii.isprint devolverá falso para cualquier carácter Unicode.
El siguiente funciona más rápido que los otros anteriores. Echar un vistazo
''''.join([x if x in string.printable else '''' for x in Str])
En 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})
Consulte esta publicación de para eliminar los signos de puntuación de cómo .translate () se compara con regex & .replace ()
Esta función usa listas de comprensión y str.join, por lo que se ejecuta en tiempo lineal en lugar de O (n ^ 2):
from curses.ascii import isprint
def printable(input):
return ''''.join(char for char in input if isprint(char))
Hasta donde yo sé, el método más pythonic / eficiente sería:
import string
filtered_string = filter(lambda x: x in string.printable, myStr)
Iterar cadenas es lamentablemente bastante lento en Python. Las expresiones regulares son más de un orden de magnitud más rápidas para este tipo de cosas. Solo tienes que construir la clase de personaje tú mismo. El módulo unicodedata es bastante útil para esto, especialmente la función unicodedata.category () . Vea la base de datos de caracteres Unicode para descripciones de las categorías.
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)
Lo mejor que he encontrado ahora es (gracias a los python-izers anteriores)
def filter_non_printable(str):
return ''''.join([c for c in str if ord(c) > 31 or ord(c) == 9])
Esta es la única forma que descubrí que funciona con caracteres / cadenas Unicode
¿Alguna mejor opción?
Para eliminar ''espacios en blanco'',
import re
t = """
/n/t<p> </p>/n/t<p> </p>/n/t<p> </p>/n/t<p> </p>/n/t<p>
"""
pat = re.compile(r''[/t/n]'')
print(pat.sub("", t))
Podría intentar configurar un filtro utilizando la función unicodedata.category()
:
printable = Set(''Lu'', ''Ll'', ...)
def filter_non_printable(str):
return ''''.join(c for c in str if unicodedata.category(c) in printable)
Consulte las propiedades de caracteres de la base de datos Unicode para las categorías disponibles