Python: remplace la chaîne par prefixStringSuffix en conservant la casse d'origine, mais en ignorant la casse lors de la recherche d'une correspondance

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

Question

Donc, ce que j'essaie de faire, c'est de remplacer une chaîne " keyword " avec     "<b>keyword</b>" dans une plus grande chaîne.

Exemple:

myString = & "HI il. Vous devriez plus haut cette personne pour le travail. Salut salut. & Quot;

mot-clé = & "salut &";

résultat que je voudrais serait:

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

Je ne saurai pas quel est le mot-clé tant que l'utilisateur n'a pas saisi le mot-clé et ne connaitra pas le corpus (myString) tant que la requête n'aura pas été exécutée.

J'ai trouvé une solution qui fonctionne la plupart du temps, mais qui comporte des faux positifs, namely it would return "<b>hi<b/>gher" qui n'est pas ce que je veux. Notez aussi que je essaie de préserver le cas du texte original, et la correspondance devrait prendre placer quel que soit le cas. Donc, si le mot clé est & "; salut &"; il devrait remplacer HI with <b>HI</b> and hi with <b>hi</b>.

Le plus proche que je suis venu utilise une version légèrement dérivée de ceci: http://code.activestate.com/recipes/576715/ mais je ne pouvais toujours pas comprendre comment faire une deuxième passe de la chaîne pour corriger tous les faux positifs mentionnés ci-dessus.

Ou en utilisant WordPunctTokenizer du NLTK (ce qui simplifie certaines choses comme la ponctuation) mais je ne suis pas sûr de savoir comment je remettrais les phrases ensemble étant donné que cela ne fonctionne pas. avoir une fonction inverse et je veux conserver la ponctuation originale de myString. Essentiel, une concaténation de tous les jetons ne renvoie pas l'original. chaîne. Par exemple, je ne voudrais pas remplacer & Quot; 7 - 7 & Quot; avec " 7-7 " lors du regroupement des jetons dans son texte d'origine si le texte d'origine contenait " 7 - 7 " ;.

J'espère que c'était assez clair. Cela semble être un problème simple, mais c’est un peu plus difficile que je ne le pensais.

Était-ce utile?

La solution

Ça va?

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

L’essentiel est d’utiliser les limites de mot , groupes et le indicateur re.I .

Autres conseils

Vous devriez pouvoir le faire très facilement avec re.sub l'aide de l'assertion de limite de mot \b, qui ne correspond qu'à une limite de mot:

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)

Ensuite, vous obtenez:

>>> 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 vous avez des critères plus compliqués pour ce qui constitue une " limite de mot, " vous devrez faire quelque chose comme:

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)

Vous pouvez modifier les [^a-zA-Z0-9] groupes pour qu'ils correspondent à tout ce que vous considérez comme & "non-mot. &";

.

Je pense que la meilleure solution serait l’expression régulière ...

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

bien sûr, vous devez d’abord rendre votre mot clé " expression régulière sécurisé " (citez tous les caractères spéciaux regex).

Voici une suggestion du comité nitpicking. : -)

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

myString.replace('higher','hire')
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top