Python:替换字符串为前缀字符串后缀,保持原始大小写,但在查找匹配时忽略大小写
我想做的事情是把一个字符串中的“keyword”替换成
"<b>keyword</b>"
在一个更大的字符串里。
举个例子:
myString = "HI there. You should higher that person for the job. Hi hi."
keyword = "hi"
我想要的结果是:
result = "<b>HI</b> there. You should higher that person for the job.
<b>Hi</b> <b>hi</b>."
我不知道用户输入的关键词是什么,也不知道myString的内容,直到查询被执行。
我找到了一种大部分时间都能用的解决方案,但有些情况会出错,
比如它会返回"<b>hi<b/>gher"
,这不是我想要的。另外,我还想保留原始文本的大小写,匹配时不考虑大小写。所以如果关键词是“hi”,它应该把
HI替换成<b>HI</b>,hi替换成<b>hi</b>。
我找到的最接近的办法是用这个稍微改动过的版本: http://code.activestate.com/recipes/576715/ 但我还是没弄明白怎么对字符串进行第二次处理,以修正上面提到的所有错误。
或者使用NLTK的WordPunctTokenizer(它简化了一些标点符号的处理),但我不确定如何把句子重新组合起来,因为它没有反向功能,而且我想保留myString的原始标点。简单来说,把所有的标记拼接起来并不能返回原始字符串。例如,如果原始文本是“7 - 7”,我不想在重新组合标记时把它替换成“7-7”。
希望我说得够清楚。这看起来是个简单的问题,但结果比我想的要复杂一些。
4 个回答
我觉得最好的办法是用正则表达式...
import re
def reg(keyword, myString) :
regx = re.compile(r'\b(' + keyword + r')\b', re.IGNORECASE)
return regx.sub(r'<b>\1</b>', myString)
当然,你首先得让你的关键词变得“正则表达式安全”(也就是把任何正则表达式中的特殊字符加上引号)。
你可以很简单地用 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
>>> 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>.'