Python: Reemplace la cadena con prefixStringSuffix manteniendo el caso original, pero ignorando el caso al buscar una coincidencia

StackOverflow https://stackoverflow.com/questions/818691

Pregunta

Entonces, lo que intento hacer es reemplazar una cadena " palabra clave " con     "<b>keyword</b>" en una cadena más grande.

Ejemplo:

myString = " Hola. Deberías elevar a esa persona para el trabajo. Hola hola. & Quot;

keyword = " hola "

El

resultado que desearía sería:

result = "<b>HI</b> there. You should higher that person for the job. <b>Hi</b> <b>hi</b>."

No sabré cuál es la palabra clave hasta que el usuario la escriba y no conocerá el corpus (myString) hasta que se ejecute la consulta.

Encontré una solución que funciona la mayor parte del tiempo, pero tiene algunos falsos positivos, namely it would return "<b>hi<b/>gher" que no es lo que quiero. También tenga en cuenta que yo Estoy tratando de preservar el caso del texto original, y la coincidencia debería tomar colocar independientemente del caso. entonces, si la palabra clave es " hi " debería reemplazar HI with <b>HI</b> and hi with <b>hi</b>.

Lo más cerca que he venido es usar una versión ligeramente derivada de esto: http://code.activestate.com/recipes/576715/ pero todavía no podía entender cómo hacer una segunda pasada de la cadena para corregir todos los falsos positivos mencionados anteriormente.

O usando el WordPunctTokenizer de NLTK (que simplifica algunas cosas como la puntuación) pero no estoy seguro de cómo volvería a armar las oraciones dado que no tengo una función inversa y quiero mantener la puntuación original de myString. Esencial, hacer una concatenación de todos los tokens no devuelve el original cuerda. Por ejemplo, no quisiera reemplazar & Quot; 7 - 7 & Quot; con & "; 7-7 &"; al reagrupar las fichas en su texto original si el texto original tenía " 7 - 7 " ;.

Espero que haya sido lo suficientemente claro. Parece un problema simple, pero resultó un poco más difícil de lo que pensaba.

¿Fue útil?

Solución

¿Esta bien?

>>> import re
>>> myString = "HI there. You should higher that person for the job. Hi hi."
>>> keyword = "hi"
>>> search = re.compile(r'\b(%s)\b' % keyword, re.I)
>>> search.sub('<b>\\1</b>', myString)
'<b>HI</b> there. You should higher that person for the job. <b>Hi</b> <b>hi</b>.'

La clave de todo esto es usar límites de palabras , grupos y re.I flag .

Otros consejos

Debería poder hacer esto muy fácilmente con re.sub usando la aserción de límite de palabra \b, que solo coincide en un límite de palabra:

import re

def SurroundWith(text, keyword, before, after):
  regex = re.compile(r'\b%s\b' % keyword, re.IGNORECASE)
  return regex.sub(r'%s\0%s' % (before, after), text)

Entonces obtienes:

>>> SurroundWith('HI there. You should hire that person for the job. '
...              'Hi hi.', 'hi', '<b>', '</b>')
'<b>HI</b> there. You should hire that person for the job. <b>Hi</b> <b>hi</b>.'

Si tiene criterios más complicados para lo que constituye un " límite de palabra, " tendrás que hacer algo como:

def SurroundWith2(text, keyword, before, after):
  regex = re.compile(r'([^a-zA-Z0-9])(%s)([^a-zA-Z0-9])' % keyword,
                     re.IGNORECASE)
  return regex.sub(r'\1%s\2%s\3' % (before, after), text)

Puede modificar los grupos [^a-zA-Z0-9] para que coincidan con cualquier cosa que considere " no word. "

Creo que la mejor solución sería la expresión regular ...

import re
def reg(keyword, myString) :
   regx = re.compile(r'\b(' + keyword + r')\b', re.IGNORECASE)
   return regx.sub(r'<b>\1</b>', myString)

por supuesto, primero debe hacer que su palabra clave " expresión regular segura " (cita los caracteres especiales de expresiones regulares).

Aquí hay una sugerencia, del comité de selección. :-)

myString = "HI there. You should higher that person for the job. Hi hi."

myString.replace('higher','hire')
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top