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

Entonces, lo que estoy tratando de hacer es reemplazar una “palabra clave” de cadena por "keyword" en una cadena más grande.

Ejemplo:

myString = “Hola. Debes mejorar a esa persona para el trabajo. Hola, hola”.

keyword = “hola”

El resultado que quisiera sería:

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

No sabré cuál es la palabra clave hasta que el usuario escriba la palabra clave y no sabré 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, a namely it would return "higher" que no es lo que quiero. También tenga en cuenta que estoy tratando de preservar el caso del texto original, y la coincidencia debe tener lugar independientemente del caso. por lo tanto, si la palabra clave es “hi”, debe reemplazar HI with HI and hi with hi.

Lo más cerca que he llegado es usar una versión ligeramente derivada de esto: http://code.activestate.com/recipes/576715/ pero todavía no pude averiguar cómo hacer una segunda pasada de la cadena para arreglar todo lo falso positivos mencionados anteriormente.

O usar el WordPunctTokenizer de NLTK (que simplifica algunas cosas como la puntuación) pero no estoy seguro de cómo volvería a juntar las frases dado que no tiene una función inversa y quiero mantener la puntuación original de myString. Esencial, hacer una concatenación de todos los tokens no devuelve la cadena original. Por ejemplo, no me gustaría reemplazar “7 – 7” con “7-7” al reagrupar las fichas en su texto original si el texto original tuviera “7 – 7”.

Espero que eso haya quedado suficientemente claro. Parece un problema simple, pero resultó un poco más difícil de lo que pensé.

¿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('\\1', myString) 'HI there. You should higher that person for the job. Hi hi.' 

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

Debería poder hacer esto muy fácilmente con re.sub usando la palabra aserción de límite \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', '', '') 'HI there. You should hire that person for the job. Hi hi.' 

Si tiene criterios más complicados para lo que constituye un “límite de palabra”, tendrá 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 una “no palabra”.

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'\1', myString) 

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

Aquí hay una sugerencia, del comité de puntería. 🙂

 myString = "HI there. You should higher that person for the job. Hi hi." myString.replace('higher','hire')