django 自定义截取中文的过滤器
django 自带的模板过滤器truncatewords和truncatewords_html 都是不支持中文的,前者是截取不带html标签的内容,后者截取带html标签的内容。为了达到截取中文的目的,按照truncatewords和思路重新编写了字符截取工具
这个新的truncatewords函数是从带html标签的内容或不带html内容中截取字符的,中英文皆可,截取之后会去掉原有的标签,只保留内容
################################################################################## #截取字符工具,不保留html ################################################################################## def truncatewords(s,num,end_text='...'): re_tag= re.compile(r'<(/)?([^ ]+?)(?: (/)| .*?)?>') re_words = re.compile(u'(&.*?;)|[\u4e00-\u9fa5]{1}|[^\u4e00-\u9fa5]{1}',re.UNICODE) s = force_unicode(s) length=int(num) if length<=0: return u'' pos = 0 words=0 data=[] out='' current_word = '' while words <= length: if words==length: break #查找第一个标签结束的> m= re_tag.search(s,pos) if not m: break pos = m.end() #开始从这个位置向后搜索字符,匹配到第一个字符,停止,检查,如果字符是<,说明匹配到了html标签了,则跳出去,否则开始检查下一个标签的> while words <= length: if words==length: break m = re_words.search(s,pos) if not m: break current_word = m.group() if current_word=='<': break else: if not m.group(1): words+=1 data.append(str(m.group())) pos+=1 else: words+=1 data.append(str(m.group())) pos=m.end() out = ''.join(data) out+=end_text return out
truncatewords_html 也是截取内容,但其保留了html标签
################################################################################## #截取字符工具,保留html ################################################################################## def truncatewords_html(s,num,end_text='...'): html4_singlets = ('br', 'col', 'link', 'base', 'img', 'param', 'area', 'hr', 'input') re_tag= re.compile(r'<(/)?([^ ]+?)(?: (/)| .*?)?>') re_words = re.compile(u'(&.*?;)|[\u4e00-\u9fa5]{1}|[^\u4e00-\u9fa5]{1}',re.UNICODE) s = force_unicode(s) length=int(num) if length<=0: return u'' pos = 0 words=0 current_word = '' open_tags=[] while words <= length: if words==length: break #查找第一个标签结束的> m= re_tag.search(s,pos) if not m: break pos = m.end() closing_tag,tagname,self_closing=m.groups() #自关闭标签不处理,或者是单标签 if self_closing or tagname in html4_singlets: pass elif closing_tag: # Check for match in open tags list try: i = open_tags.index(tagname) except ValueError: pass else: #移除该标签,说明该标签已经闭合 open_tags.remove(tagname) else: #把标签加入到仍然打开的标签中 open_tags.insert(0, tagname) #开始从这个位置向后搜索字符,匹配到第一个字符,停止,检查,如果字符是<则跳出去,否则开始检查下一个标签的> while words <= length: if words==length: break m = re_words.search(s,pos) if not m: break current_word = m.group() if current_word=='<': break else: if not m.group(1): words+=1 pos+=1 else: words+=1 pos=m.end() #如果本身的大小就不够,则不加结尾 if pos==len(s): return s out = s[:pos] if end_text: out += ' ' + end_text # Close any tags still open for tag in open_tags: out += '</%s>' % tag # Return string return out