Python: Reemplace la cadena con prefixStringSuffix manteniendo el caso original, pero ignorando el caso al buscar una coincidencia
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 "
Elresultado 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.
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')