Питон:Замените строку на prefixStringSuffix, сохраняя исходный регистр, но игнорируя регистр при поиске соответствия
Вопрос
Итак, что я пытаюсь сделать, это заменить строку "ключевое слово" на
"<b>keyword</b>"
в более крупной строке.
Пример:
myString = "Всем ПРИВЕТ.Вы должны повысить квалификацию этого человека для этой работы.Привет, привет".
ключевое слово = "привет"
результат, которого я хотел бы, был бы:
result = "<b>HI</b> there. You should higher that person for the job.
<b>Hi</b> <b>hi</b>."
Я не буду знать, что это за ключевое слово, пока пользователь не введет ключевое слово и не буду знать корпус (myString), пока не будет выполнен запрос.
Я нашел решение, которое работает большую часть времени, но имеет несколько ложных срабатываний,
namely it would return "<b>hi<b/>gher"
а это не то, чего я хочу.Также обратите внимание, что я
пытаюсь сохранить регистр исходного текста, и сопоставление должно происходить
независимо от регистра.таким образом, если ключевое слово "hi", оно должно заменить
HI with <b>HI</b> and hi with <b>hi</b>.
Самое близкое, к чему я пришел, - это использовать слегка производную версию этого:http://code.activestate.com/recipes/576715/ но я все еще не мог понять, как выполнить второй проход строки, чтобы исправить все упомянутые выше ложные срабатывания.
Или с помощью WordPunctTokenizer от NLTK (который упрощает некоторые вещи, такие как пунктуация) но я не уверен, как бы я собрал предложения обратно вместе, учитывая, что это не так есть обратная функция, и я хочу сохранить исходную пунктуацию myString .Важно, что выполнение конкатенации всех токенов не возвращает исходную строку .Например, я бы не хотел заменять "7 - 7" на "7-7" при перегруппировке токенов в исходный текст, если в исходном тексте было "7 - 7".
Надеюсь, это было достаточно ясно.Кажется, задача простая, но она оказалась немного сложнее, чем я думал.
Решение
Это нормально?
>>> 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>.'
Ключом ко всему этому является использование границы слов, Группы и тот флаг re.I.
Другие советы
Вы должны быть в состоянии сделать это очень легко с re.sub
использование слова утверждение границы \b
, который совпадает только на границе слова:
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)
Тогда вы получите:
>>> 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>.'
Если у вас есть более сложные критерии для того, что представляет собой "границу слов", вам нужно будет сделать что-то вроде:
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)
Вы можете изменить [^a-zA-Z0-9]
группы, соответствующие всему, что вы считаете "не-словом".
Я думаю, лучшим решением было бы регулярное выражение...
import re
def reg(keyword, myString) :
regx = re.compile(r'\b(' + keyword + r')\b', re.IGNORECASE)
return regx.sub(r'<b>\1</b>', myString)
конечно, сначала вы должны сделать свое ключевое слово "безопасным для регулярных выражений" (заключать в кавычки любые специальные символы регулярных выражений).
Вот одно предложение от комитета по придиркам.:-)
myString = "HI there. You should higher that person for the job. Hi hi."
myString.replace('higher','hire')