Reemplazo de expresiones regulares para una gran cantidad de pares de reemplazo de búsqueda [cerrado]
Frecuentes
Visto 601 veces
2
Quiero poder realizar búsquedas a gran escala y reemplazar documentos para fines de normalización de texto.
Por ejemplo:
- Encuentra todos los usos de EE.UU., USA y reemplazar con Estados Unidos de America
- Encuentre todos los símbolos de unión (&) y reemplácelos con la palabra y
También quiero poder agregar nuevas reglas al sistema sin tener que cambiar ningún código. Por lo tanto, los pares de reemplazo de búsqueda se almacenan en un almacén de datos, lo que significa que cualquiera puede agregar, actualizar y eliminar las reglas.
He estado trabajando con el módulo Python re, que es bastante agradable e idealmente me gustaría pasar una lista de tuplas al subcomando para que luego revise cada una y haga los reemplazos. ¿Hay una mejor manera de hacer esto que no sea iterar sobre una lista de tuplas y luego crear una expresión regular para cada una? Es muy lento e ineficiente, especialmente con documentos grandes:
replacements = [
r('USA','United States Of America'),
(r'U\.S\.A','United States Of America'),
(r'US of A', 'United States of America')]
for replacement in replacements:
document = re.sub(replacement[0],replacement[1],document
3 Respuestas
1
Ninguno de sus ejemplos requiere expresiones regulares. ¿Por qué no probar el buen reemplazo de cuerdas?
replacements = [
('USA','United States Of America'),
('U\.S\.A','United States Of America'),
('US of A', 'United States of America')]
for replacement in replacements:
document = document.replace(replacement[0], replacement[1])
Parece que sería lento, pero debe compararlo antes de descartar el enfoque. Python es bastante bueno en cosas como esta y los resultados pueden sorprenderte.
Si realmente necesita expresiones regulares, es probable que vea un gran impulso al compilarlas:
replacements = [
(re.compile('USA'),'United States Of America'),
(re.compile('U\.S\.A'),'United States Of America'),
(re.compile('US of A'), 'United States of America')]
for pattern, replacement in replacements:
document = pattern.sub(replacement, document)
Esto le ahorra a Python el esfuerzo de tener que volver a compilar esas expresiones regulares cada vez que las usa.
Si solo necesita expresiones regulares algunas veces, considere realizar dos pasadas por el documento: una con expresiones regulares y otra con reemplazo de cadena. O si necesita un pedido específico de reemplazos, podría tener algo como:
replacements = [
(re.compile('USA'),'United States Of America'),
('foo', 'bar'),
(re.compile('U\.S\.A'),'United States Of America'),
('spam', 'eggs'),
(re.compile('US of A'), 'United States of America')]
for pattern, replacement in replacements:
try:
document = pattern.sub(replacement, document)
except AttributeError:
document = document.replace(pattern, replacement)
contestado el 22 de mayo de 12 a las 16:05
El uso de string.replace estaría bien si no desea mantener el caso del texto original, ya que no le permite ignorar el caso como puede con una expresión regular. Por lo tanto, tendría que escribir en mayúsculas o minúsculas el cuerpo del texto y también los términos que está buscando, lo que afecta la salida. - marca unsworth
0
Echa un vistazo a Google Refine.
Google Refine, una poderosa herramienta para trabajar con datos desordenados
contestado el 22 de mayo de 12 a las 15:05
0
Tengo un archivo de culo grande con 6 MB de texto. Es una compilación de varios archivos del Proyecto Gutenberg.
Intentando esto:
reps = [
(r'\bthousand\b','>>>>>1,000<<<<<'),
(r'\bmillion\b',">>>>>1e6<<<<<"),
(r'\b[Hh]undreds\b',">>>>>100's<<<<<"),
(r'\bSherlock\b', ">>>> SHERLOCK <<<<")
]
t1=time.time()
out=[]
rsMade=0
textLength=0
NewTextLen=0
with open('big.txt') as BigAssF:
for line in BigAssF:
textLength+=len(line)
for pat, rep in reps:
NewLine=re.subn(pat,rep,line)
out.append(NewLine[0])
NewTextLen+=len(NewLine[0])
rsMade+=NewLine[1]
print 'Text Length: {:,} characters'.format(textLength)
print 'New Text Length: {:,} characters'.format(NewTextLen)
print 'Replacements Made: {}'.format(rsMade)
print 'took {:.4} seconds'.format(time.time()-t1)
Imprime:
Text Length: 6,488,666 characters
New Text Length: 6,489,626 characters
Replacements Made: 96
took 2.22 seconds
Lo que me parece adecuadamente rápido.
Es posible que tenga algunos problemas con su línea de código:
document = re.sub(replacement[0],replacement[1],document
si eso no es un error tipográfico.
¿Qué tan rápido esperas que sea?
contestado el 22 de mayo de 12 a las 18:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas python regex nlp text-processing or haz tu propia pregunta.
Esta pregunta no es realmente adecuada para el formato de preguntas y respuestas de SO. (StackOverflow no es un motor de recomendaciones) - David Cain
@Mark, hay una pregunta en alguna parte, sugiere volver a escribirla. - NWS
Vale, he tenido en cuenta lo que has dicho y he intentado plantearlo como una pregunta. - Mark Unsworth
Bien, esta es una pregunta mucho más clara. - David Cain
Reemplazar ciegamente & con y es una idea terrible. Puede ser parte de nombres formales. ¿Debería "S&P 500" convertirse en "S and P 500"? - Kaz