Python: substitua a string pelo prefixstringsuffix mantendo o caso original, mas ignorando o caso ao procurar a partida

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

Pergunta

Então, o que estou tentando fazer é substituir uma string "palavra -chave" por "<b>keyword</b>"em uma corda maior.

Exemplo:

mystring = "Olá. Você deve aumentar essa pessoa para o trabalho. Olá."

Keyword = "oi"

resultado eu gostaria que seria:

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

Não saberei qual a palavra -chave até que o usuário digite a palavra -chave e não conhecerá o corpus (mystring) até que a consulta seja executada.

Encontrei uma solução que funciona na maioria das vezes, mas tem alguns falsos positivos,namely it would return "<b>hi<b/>gher"que não é o que eu quero. Observe também que estou tentando preservar o caso do texto original e a correspondência deve ocorrer independentemente do caso. Portanto, se a palavra -chave for "oi", deve substituirHI with <b>HI</b> and hi with <b>hi</b>.

O mais próximo que cheguei é usar uma versão ligeiramente derivada disso:http://code.activestate.com/recipes/576715/Mas ainda não consegui descobrir como fazer um segundo passe da string para corrigir todos os falsos positivos mencionados acima.

Ou usando o WordPunctTokenizer do NLTK (que simplifica algumas coisas como pontuação), mas não tenho certeza de como montaria as frases novamente, pois não tem uma função reversa e quero manter a pontuação original do mystring. Essencial, fazer uma concatenação de todos os tokens não retorna a string original. Por exemplo, eu não gostaria de substituir "7 - 7" por "7-7" ao reagrupar os tokens em seu texto original, se o texto original tivesse "7 - 7".

Espero que tenha sido claro o suficiente. Parece um problema simples, mas ficou um pouco mais difícil do que eu pensei.

Foi útil?

Solução

Isso ok?

>>> 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>.'

A chave para a coisa toda é usar limites da palavra, grupos e a bandeira re.i.

Outras dicas

Você deve ser capaz de fazer isso com muita facilidade com re.sub Usando a afirmação de limite da palavra \b, que corresponde apenas a um limite da palavra:

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)

Então você recebe:

>>> 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>.'

Se você tiver critérios mais complicados para o que constitui um "limite de palavras", você terá que fazer 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)

Você pode modificar o [^a-zA-Z0-9] grupos para combinar com qualquer coisa que você considere uma "não palavra".

Eu acho que a melhor solução seria a expressão 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)

Obviamente, você deve primeiro tornar sua palavra -chave "expressão regular segura" (cite qualquer caractere especial Regex).

Aqui está uma sugestão, do Comitê de Nitpicking. :-)

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

myString.replace('higher','hire')
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top