2

I have a template tag like this:

@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)

It changes the (bkz: something) to linked (bkz: something). It works fine but only once. When I put a few (bkz: sth) to my object. It only renders the last one in object as changed version. How can I run this as much as necessary? Thanks.

Jason S
  • 13,538
  • 2
  • 37
  • 42
malisit
  • 1,253
  • 2
  • 17
  • 36

2 Answers2

0

Take out the start and end groups. They are not needed; you want to match your (bkz: something), not what's around it.

Use non-greedy matching A .* in a regex will try to match as much as possible at a time. Use .*? to avoid clobbering future instances of the pattern.

pattern = re.compile(r"\(bkz: (?P<bkz>.*?)\)")
Jason S
  • 13,538
  • 2
  • 37
  • 42
0

This one worked.

@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)
malisit
  • 1,253
  • 2
  • 17
  • 36