2009-04-16 19 views
5

Soy un novato total de Python, por favor tengan paciencia conmigo. Quiero que python escanee una página de html y reemplace instancias de entidades de Microsoft Word con algo compatible con UTF-8.Algunas preguntas básicas de Python

Mi pregunta es, ¿cómo se hace eso en Python (lo he buscado en Google pero hasta ahora no he encontrado una respuesta clara)? Quiero sumergir mi dedo del pie en las aguas de Python, así que creo que algo tan simple como este es un buen lugar para comenzar. Parece que yo tendría que:

  1. carga texto pegado de MS Word en una variable
  2. plazo algún tipo de reemplazar la función de los contenidos
  3. de salida que

En PHP que lo haría hazlo así:

$test = $_POST['pasted_from_Word']; //for example “Going Mobile” 

function defangWord($string) 
{ 
    $search = array(
     (chr(0xe2) . chr(0x80) . chr(0x98)), 
     (chr(0xe2) . chr(0x80) . chr(0x99)), 
     (chr(0xe2) . chr(0x80) . chr(0x9c)), 
     (chr(0xe2) . chr(0x80) . chr(0x9d)), 
     (chr(0xe2) . chr(0x80) . chr(0x93)), 
     (chr(0xe2) . chr(0x80) . chr(0x94)), 
     (chr(0x2d)) 
    ); 

    $replace = array(
     "‘", 
     "’", 
     "“", 
     "”", 
     "–", 
     "—", 
     "–" 
    ); 

    return str_replace($search, $replace, $string); 
} 

echo defangWord($test); 

¿Cómo lo harías en Python?

EDITAR: Hmmm, vale, ignora mi confusión sobre UTF-8 y entidades por el momento. La entrada contiene texto pegado de MS Word. Las cosas como las comillas están apareciendo como símbolos impares. Varias funciones de PHP que utilicé para tratar de arreglarlo no me daban los resultados que quería. Al ver esos símbolos impares en un editor hexadecimal, vi que correspondían a los símbolos que utilicé anteriormente (0xe2, 0x80, etc.). Así que simplemente cambié los caracteres extraños con entidades HTML. Entonces, si el bit que tengo arriba ya es UTF-8, ¿qué está pegando desde MS Word que está causando los símbolos impares?

EDIT2: Así que me puse a aprender un poco sobre Python y descubrí que realmente no entiendo la codificación. El problema que estaba tratando de resolver se puede manejar simplemente teniendo una codificación independiente de extremo a extremo. Si el formulario de entrada es UTF-8, la base de datos que almacena la entrada es UTF-8 y la página que lo genera es UTF-8 ... pegar desde Word funciona bien. No se necesitan funciones especiales. Ahora, sobre aprender un poco de Python ...

+1

+1: "defangWord()" ... ¡Me encanta! :-) –

Respuesta

20

Primero que nada, esas no son entidades de Microsoft Word-ellos son UTF-8. Los está convirtiendo a entidades HTML.

La forma Pythonic escribir algo como:

chr(0xe2) . chr(0x80) . chr(0x98) 

sería:

'\xe2\x80\x98' 

Pero Python ya se ha incorporado en la funcionalidad para el tipo de conversión que desea hacer:

def defang(string): 
    return string.decode('utf-8').encode('ascii', 'xmlcharrefreplace') 

Esto reemplazará los códigos UTF-8 en una cadena para caracteres como con entidades numéricas como “.

Si desea reemplazar aquellas entidades numéricas con el nombre en lo posible los:

import re 
from htmlentitydefs import codepoint2name 

def convert_match_to_named(match): 
    num = int(match.group(1)) 
    if num in codepoint2name: 
     return "&%s;" % codepoint2name[num] 
    else: 
     return match.group(0) 

def defang_named(string): 
    return re.sub('&#(\d+);', convert_match_to_named, defang(string)) 

y usarlo de esta manera:

>>> defang_named('\xe2\x80\x9cHello, world!\xe2\x80\x9d') 
'“Hello, world!”' 

Para completar la respuesta, el código equivalente a su ejemplo para procesar un archivo sería algo como esto:

# in Python, it's common to operate a line at a time on a file instead of 
# reading the entire thing into memory 

my_file = open("test100.html") 
for line in my_file: 
    print defang_named(line) 
my_file.close() 

Tenga en cuenta que esta respuesta está dirigida a Python 2.5; la situación Unicode es radicalmente diferente para Python 3+.

También estoy de acuerdo con el comentario de bobince a continuación: si puede mantener el texto en formato UTF-8 y enviarlo con el tipo de contenido y el juego de caracteres correctos, hágalo; si necesita que esté en ASCII, entonces quédese con las entidades numéricas, realmente no hay necesidad de usar las nombradas.

+0

+1 para xmlcharrefreplace - no hay necesidad de entidades con nombre HTML hoy realmente. Pero realmente, deje el UTF-8 solo, las citas inteligentes intactas. Siempre que lo publique con el encabezado/metaetiqueta "charset" correcto, no hay problema. – bobince

+0

+1 para señalar que las entidades son UTF-8 y no algunas rarezas MS ;-) (y para una respuesta bien escrita en general, también) –

+0

Estoy confundido. El documento que estoy importando en el ejemplo está lleno de símbolos extraños que corresponden a las comillas tipográficas de MS Word. Si los coloco directamente en una página con codificación UTF-8, obtengo símbolos extraños. Si los convierto usando mi código de ejemplo, se procesarán bien. Entonces, ¿qué son antes de convertirme? – Stuart

3

El código de Python tiene el mismo esquema.

Simplemente reemplace todos los PHP-ismos con Python-isms.

Comience por crear un objeto File. El resultado de un file.read() es un objeto string. Las cadenas tienen una operación de "reemplazo".

2

Su mejor apuesta para limpiar Word HTML es usar HTML Tidy que tiene un modo solo para eso. Hay a few Python wrappers que puede usar si necesita hacerlo programáticamente.

1

Como dijo S.Lott, el código de Python sería muy, muy similar: las únicas diferencias serían esencialmente las llamadas/declaraciones de función.

No creo que Python tiene un equivalente directo a file_get_contents(), pero ya que se puede obtener una gran variedad de las líneas en el archivo, a continuación, puede unirse a ellos por saltos de línea, así:

sample = '\n'.join(open(test, 'r').readlines()) 

EDITAR : no importa, hay una manera mucho más fácil: sample = file(test).read()

cadena sustitución es casi exactamente el mismo que str_replace():

sample = sample.replace(search, replace) 

y dando salida es tan simple como una declaración print:

print defang_word(sample) 

Así como se puede ver, las dos versiones se ven casi exactamente el mismo.

+0

archivo ('foo.txt'). Read() – Justus

+0

Bueno editado por llamada. – hbw

+0

@Justus, no 'archivo (nombre) .read()' descriptores de archivos de fuga, ya que nunca llama a cerrar? –

Cuestiones relacionadas