Django模板标签中的正则只匹配一次

2 投票
2 回答
1522 浏览
提问于 2025-04-18 15:38

我有一个这样的模板标签:

@register.filter(name='bknz')
def bknz(text):
    pattern = re.compile(r"(?P<start>.*)\(bkz: (?P<bkz>.*)\)(?P<end>.*)")
    link = r'\g<start>(bkz: <a href="/baslik/\g<bkz>"  title="%\g<bkz> search Twitter">\g<bkz></a>)\g<end>'
    text = pattern.sub(link,text)
    return mark_safe(text)

这个标签会把(bkz: 某个东西)变成带链接的(bkz: 某个东西)。它运行得很好,但是只能用一次。当我在我的对象里放几个(bkz: 某个东西)时,它只把对象里的最后一个变成了修改后的版本。我该怎么做才能让它多次运行呢?谢谢。

2 个回答

0

去掉开头和结尾的分组。 这些分组其实没必要;你想要匹配的是 (bkz: something) 这个部分,而不是它周围的东西。

使用非贪婪匹配。 在正则表达式中,.* 会尽量多地匹配内容。为了避免覆盖后面可能出现的相同模式,应该使用 .*?

pattern = re.compile(r"\(bkz: (?P<bkz>.*?)\)")
0

这个方法有效。

@register.filter(name='bknz')
def bknz(text):
    pattern = re.compile(r"(?P<start>.*?)\(bkz: (?P<bkz>[^)]*)\)(?P<end>.*?)")
    link = r'\g<start>(bkz: <a href="/baslik/\g<bkz>"  title="\g<bkz>">\g<bkz></a>)\g<end>'
    text = pattern.sub(link, text)
    return mark_safe(text)

撰写回答