我正在创建一个django过滤器,用于从列表中将'a'标签插入到给定的字符串中。
这是我到目前为止所做的:
def tag_me(text):
tags = ['abc', 'def', ...]
tag_join = "|".join(tags)
regex = re.compile(r'(?=(.))(?:'+ tag_join + ')', flags=re.IGNORECASE)
return regex.sub(r'<a href="/tag/\1/">\1</a>', text)
示例:
tag_me('some text def')
返回:
'some text <a href="/tag/d/">d</a>'
预期:
'some text <a href="/tag/def/">def</a>'
问题出在regex.sub匹配但只返回第一个字符。我在最后一行捕获/使用\ 1的方式有问题吗?
答案 0 :(得分:3)
请注意,问题中的序列(?: ...)
特别关闭捕获。请参阅re
documentation(约1/5至页),其中(重点已添加)说:
(?:...)
常规括号的非捕获版本。匹配括号内的正则表达式,但在执行匹配或稍后在模式中引用后,无法检索与组匹配的子字符串。
如前面的回答所述,'('+ tag_join + ')'
有效,或者如果目标文本中使用了转义符,则使用建议的"|".join(re.escape(tag) for tag in tags)
版本。
答案 1 :(得分:2)
您正在捕捉(.)
部分,这只是一个字符。
我不确定我是否遵循正则表达式 - 简化版r'('+ tag_join + ')'
适用于您的示例。
请注意,如果您的代码名称中除了字母数字字符之外的任何其他内容,您还可以执行以下操作:
tag_join = "|".join(re.escape(tag) for tag in tags)
答案 2 :(得分:2)
简单地做
import re
def tag_me(text):
tags = ['abc', 'def']
reg = re.compile("|".join(tags).join('()'),
flags=re.IGNORECASE)
return reg.sub(r'<a href="/tag/\1/">\1</a>', text)
print ' %s' % tag_me('some text def')
print 'wanted: some text <a href="/tag/def/">def</a>'
那是因为你写了一个未被捕获的小组(?:....)
,然后你必须把这个令人不安的(?=(.))
放在前面。
答案 3 :(得分:1)
这应该这样做
def tag_me(text):
tags = ['abc', 'def', ]
tag_join = "|".join(tags)
pattern = r'('+tag_join+')'
regex = re.compile(pattern, flags=re.IGNORECASE)
return regex.sub(r'<a href="/tag/\1/">\1</a>', text)