python替换多个单词保留案例

时间:2015-05-17 09:22:25

标签: python regex django str-replace

我正在尝试在django中编写一个基于搜索查询突出显示单词的过滤器。例如,如果我的字符串包含this is a sample string that I want to highlight using my filter而我的搜索存根是samring,那么我想要的输出是:

this is a <mark>sam</mark>ple st<mark>ring</mark> that I want to highlight using my filter

我正在使用here的答案来替换多个单词。我已经提供了以下代码:

import re

words = search_stubs.split()
rep = dict((re.escape(k), '<mark>%s</mark>'%(k)) for k in words)
pattern = re.compile('|'.join(rep.keys()))
text = pattern.sub(lambda m : rep[re.escape(m.group(0))], text_to_replace)

但是,如果出现区分大小写,则会中断。例如,如果我有字符串Check highlight function,而我的搜索存根包含check,则会中断。

在这种情况下,所需的输出自然是:

<mark>Check</mark> highlight function

2 个答案:

答案 0 :(得分:1)

你不需要在这里找字典。 (?i)称为不区分大小写的修饰符有助于进行不区分大小写的匹配。

>>> s = "this is a sample string that I want to highlight using my filter"
>>> l = ['sam', 'ring']
>>> re.sub('(?i)(' + '|'.join(map(re.escape, l)) + ')', r'<mark>\1</mark>', s)
'this is a <mark>sam</mark>ple st<mark>ring</mark> that I want to highlight using my filter'

示例2:

>>> s = 'Check highlight function'
>>> l = ['check']
>>> re.sub('(?i)(' + '|'.join(map(re.escape, l)) + ')', r'<mark>\1</mark>', s)
'<mark>Check</mark> highlight function'

答案 1 :(得分:1)

执行此操作的简单方法是不尝试构建将每个单词映射到其标记等效的dict,并且只使用捕获组和对它的引用。然后,您只需使用IGNORECASE标志进行不区分大小写的搜索。

pattern = re.compile('({})'.format('|'.join(map(re.escape, words))),
                     re.IGNORECASE)
text = pattern.sub(r'<mark>\1</mark>', text_to_replace)

例如,如果text_to_replace是:

I am Sam. Sam I am. I will not eat green eggs and spam.

...然后text将是:

I am <mark>Sam</mark>. <mark>Sam</mark> I am. I will not eat green eggs and spam

如果你真的 想按照自己的方式去做,你可以。例如:

text = pattern.sub(lambda m: rep[re.escape(m.group(0))].replace(m, m.group(0)),
                   text_to_replace)

但那会很愚蠢。您正在构建一个价值中嵌入了'sam'的字典,因此您可以将'sam'替换为'Sam&#39;你实际上匹配了。

有关组和引用的详情,请参阅正则表达式HOWTO中的Grouping;有关在替换中使用引用的详细信息,请参阅re.sub文档。