尝试在 Django 中编写自定义模板标签,在文本中找到 phone 数字并将其转换为 link

Trying to write a custom template tag in Django that finds a phone number in text and converts it to a link

我想将此字符串 tel:123-456-7890.1234 转换为 html 中的 a link。最终输出将是 <a href="tel:1234567890,1234">123-456-7890 ext 1234</a>

我对 Regex 不是很好,我真的很接近,但我需要一些帮助。我知道我并没有完全掌握正则表达式和输出。我该如何更改才能使其正常工作?

import re

@register.filter(name='phonify')
@stringfilter
def phonify(val):
    """
    Pass the string 'tel:1234' to the filter and the right tel link is returned.
    """
    # find every instance of 'tel' and then get the number after it
    for tel in re.findall(r'tel:(\d{3}\D{0,3}\d{3}\D{0,3}\d{4})\D*(\d*)', val):
        # format the tag for each instance of tel
        tag = '<a href="tel:{}">{}</a>'.format(tel, tel)
        # replace the tel instance with the new formatted html
        val = val.replace('tel:{}'.format(tel), tag)
    # return the new output to the template context
    return val

我添加了 wagtail 标签,因为我在 Wagtail 中看到了其他解决方案,这是 Wagtail 需要的东西,所以这可能对其他人有帮助。

您可以使用 re.sub 执行查找和替换:

import re

@register.filter(name='phonify')
@stringfilter
def phonify(val):
    tel_rgx = r'tel:(\d{3}\D{0,3}\d{3}\D{0,3}\d{4}\D*\d*)'
    return re.sub(tel_rgx, r'<a href="tel:"></a>', val)

但是请注意,在您的模板中,您需要将结果标记为 "safe",否则它会将 < 替换为 &lt; 等,从而呈现 <a href=作为 text.

您也可以在模板过滤器中将字符串标记为安全:

import re
from django.utils.safestring import <b>mark_safe</b>

@register.filter(name='phonify')
@stringfilter
def phonify(val):
    tel_rgx = r'tel:(\d{3}\D{0,3}\d{3}\D{0,3}\d{4}\D*\d*)'
    return <b>mark_safe(</b>re.sub(tel_rgx, r'<a href="tel:"></a>', val)<b>)</b>

无论您如何执行此操作,它都会将所有项目标记为安全的,甚至标记等是原始字符串的一部分,因此应该进行转义。因此,我不确定这是个好主意。