Python: Ersetzen Sie die String durch PräfixStringsuffix Original -Fall, ignorieren Sie jedoch den Fall bei der Suche nach Übereinstimmung

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

Frage

Ich versuche also zu ersetzen ein Zeichenfolge "Keyword" durch "<b>keyword</b>"in einer größeren Saite.

Beispiel:

MyString = "Hallo. Du solltest diese Person für den Job höher machen. Hallo Hallo."

keyword = "hi" "

Das Ergebnis würde ich wollen: wäre:

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

Ich werde nicht wissen, was das Schlüsselwort, bis der Benutzer das Schlüsselwort eingibt und den Korpus (MyString) erst kennt, wenn die Abfrage ausgeführt wird.

Ich habe eine Lösung gefunden, die die meiste Zeit funktioniert, aber einige falsch positive Ergebnisse hat,namely it would return "<b>hi<b/>gher"Was ist nicht das, was ich will. Beachten Sie auch, dass ich versuche, den Fall des Originaltextes zu bewahren, und die Übereinstimmung sollte unabhängig vom Fall stattfinden. Wenn das Schlüsselwort also "hi" ist, sollte es ersetzenHI with <b>HI</b> and hi with <b>hi</b>.

Am nächsten kam, dass ich eine leicht abgeleitete Version davon verwendet habe:http://code.activestate.com/recipes/576715/Aber ich konnte immer noch nicht herausfinden, wie man einen zweiten Durchgang der Zeichenfolge macht, um alle oben genannten falsch -positiven Ergebnisse zu beheben.

Oder verwenden Sie den Wortpuntokenizer des NLTK (was einige Dinge wie Interpunktion vereinfacht), aber ich bin mir nicht sicher, wie ich die Sätze wieder zusammensetzen würde, da sie keine umgekehrte Funktion hat, und ich möchte die ursprüngliche Interpunktion von MyString beibehalten. Essentiell, eine Verkettung aller Token durchzuführen, gibt die ursprüngliche Zeichenfolge nicht zurück. Zum Beispiel möchte ich "7 - 7" nicht durch "7-7" ersetzen, wenn ich die Token in seinen ursprünglichen Text neu gruppiere, wenn der Originaltext "7 - 7" hätte.

Hoffe das war klar genug. Scheint ein einfaches Problem zu sein, aber es ist ein bisschen schwieriger als ich dachte.

War es hilfreich?

Lösung

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

Der Schlüssel zum Ganzen ist die Verwendung Wortgrenzen, Gruppen und die Re.i Flag.

Andere Tipps

Sie sollten dies sehr einfach mit tun können re.sub Verwenden der Wortgrenzenbehandlung \b, was nur mit einer Wortgrenze übereinstimmt:

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)

Dann bekommst du:

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

Wenn Sie kompliziertere Kriterien für das haben, was eine "Wortgrenze" ausmacht, müssen Sie so etwas wie:

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)

Sie können die ändern [^a-zA-Z0-9] Gruppen, die alles entsprechen, was Sie als "Nicht-Wort" betrachten.

Ich denke, die beste Lösung wäre ein regelmäßiger Ausdruck ...

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

Natürlich müssen Sie zuerst Ihr Schlüsselwort "regulärer Ausdruck sicher" machen (zitieren Sie alle Regex -Sonderzeichen).

Hier ist ein Vorschlag aus dem Nitpicking -Komitee. :-)

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

myString.replace('higher','hire')
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top