我试图在Django中实现一个WikiLink模板过滤器,它根据页面的存在情况查询数据库模型以给出不同的响应,这与Wikipedia的red links相同。过滤器不会引发错误,但不会对输入执行任何操作。在
WikiLink定义为:[[ThisIsAWikiLink | This is the alt text]]
下面是一个不查询数据库的工作示例:
from django import template
from django.template.defaultfilters import stringfilter
from sites.wiki.models import Page
import re
register = template.Library()
@register.filter
@stringfilter
def wikilink(value):
return re.sub(r'\[\[ ?(.*?) ?\| ?(.*?) ?\]\]', r'<a href="/Sites/wiki/\1">\2</a>', value)
wikilink.is_safe = True
输入(value
)是一个多行字符串,包含HTML和许多wikilink。在
预期的输出将[[ThisIsAWikiLink | This is the alt text]]
替换为
<a href="/Sites/wiki/ThisIsAWikiLink">This is the alt text</a>
或如果数据库中不存在“thisIsawiLink”:
<a href="/Sites/wiki/ThisIsAWikiLink/edit" class="redlink">This is the alt text</a>
以及返回值。在
以下是非工作代码(根据评论/答案编辑):
^{pr2}$代码需要做的是:
更新后的问题是: 哪种正则表达式(方法)可以返回WikiLinks的python列表,该列表可以被修改并用于替换原始匹配(在被修改之后)。在
编辑:
我想这样做:
def wikilink(value):
regex = re.magic_method(r'\[\[ ?(.*?) ?\| ?(.*?) ?\]\]', value)
foreach wikilink in regex:
alias = wikilink.group(0)
text = wikilink.group(1)
if(alias exists in Page):
regex.sub("<a href="+alias+">"+ text +"</a>")
else:
regex.sub("<a href="+alias+" class='redlink'>"+ text +"</a>")
return value
如果您的字符串中除了wiki链接之外还包含其他文本,那么您的过滤器将无法工作,因为您使用的是}。
re.match
,而不是{re.match
匹配字符串的开头。re.search
匹配字符串中的任何位置。见matching vs. searching。在另外,您的regex使用贪婪的
*
,因此如果一行包含多个wiki链接,那么它将无法工作。使用*?
使其非贪婪:编辑:
至于如何修复代码的提示,我建议您使用^{} with a callback 。优点是:
以下是实施的示意图:
^{pr2}$这类问题很快就会落到一小部分单元测试中。在
可以单独测试的过滤器片段(通过一些代码重组):
这会帮助你隔离出哪里出了问题。您可能会发现,需要重新布线regexp,以考虑|周围的可选空格。在
而且,乍一看,你的过滤器似乎是可以利用的。您声称结果是安全的,但是您没有过滤alt文本中的脚本标记之类的恶心。在
代码:
样本结果:
^{pr2}$一般评论:
我认为这种方法很快就会遇到性能问题。在
相关问题 更多 >
编程相关推荐