【问题标题】:Performing text processing on flatpage content to include handling of custom tag对平面页面内容执行文本处理,包括处理自定义标签
【发布时间】:2011-06-30 13:31:10
【问题描述】:

我在我的项目中使用 flatpages 应用程序来管理一些 html 内容。该内容将包括图像,因此我制作了一个ContentImage 模型,允许用户使用管理面板上传图像。 然后,用户应该能够将这些图像包含在平面页面的内容中。他当然可以通过在<img> 标签中手动输入图片网址来做到这一点,但这不是我想要的。

为了让包含图片更方便,我正在考虑这样的事情:

  • 用户编辑了一个额外的,比如说CustomFlatPage 模型的pre_content 字段(我已经在使用自定义平面模型)
  • 他没有直接定义<img> 标签,而是使用自定义标签,例如[img=...],其中...ContentImage 实例的名称
  • 现在最难的部分:在保存CustomFlatPage 之前,检查pre_content 字段是否存在所有[img=...],并按如下方式处理它们:
  • 搜索ContentImage 模型是否存在具有给定名称的图像实例,如果存在,则将[img=...] 替换为正确的<img> 标签。
  • flatpage 实际content 填充处理过的pre_content,然后保存flatpage(pre_content 保持不变,由用户编辑)

我无法应付的部分是文本处理。我应该使用正则表达式吗?显然,对于大字符串,它们可能会很慢。 以及如何组织逻辑?我认为这是一个算法问题,但我对 Python 中的文本处理还不够熟悉,无法自己完成。

谁能给我点线索?

【问题讨论】:

  • 我喜欢这样。通常答案是:“不要使用正则表达式,使用 html 解析器”,但是自定义标签呢?我也想知道
  • PS:BeautifulSoup 是一个很棒的 HTML 解析库。如果您愿意查看源代码,我相信这将是一个很棒的资源。它是处理甚至损坏的 html 的王者。我开始认为正则表达式可能适合您的标签,因为它不涉及结束标签的复杂性,但[img=][ img = ] 的一些可能变体
  • 谢谢。我会看看这个BeautilfulSoup 来源。也许我可以从中借鉴一些想法。

标签: python django algorithm text-processing


【解决方案1】:

我终于使用正则表达式实现了这一点。我决定,自定义标签内不允许有空格。主要的文本处理函数如下所示:

import re
from django.utils.translation import ugettext as _

def process_image_tags(text, ImageModel):
    '''image tag usage:
        ... some text ... [img=image_name:image_class(optional)] ... some text ...
    '''
    t1 = re.split(r'(\[img=[a-z0-9\-_\:]+\])', text)
    t2 = []
    for i in t1:
        if i[:5] == '[img=':
            attrs = i[5:-1].split(':')
            name_attr = attrs[0] #name attribute
            error = None
            try:
                image = ImageModel.objects.get(name=name_attr)
            except ImageModel.DoesNotExist:
                error = '<span class="image_tag_error">%s</span>' % _('Image with given name not found')
            except ImageModel.MultipleObjectsReturned:
                error = '<span class="image_tag_error">%s</span>' % _('More than one image found')
            if not error:
                p = ['<img']
                p.append('src="%s"' % image.image.url) 
                if len(attrs) > 1:
                    p.append('class="%s"' % attrs[1]) #class attribute
                if image.description:
                    p.append('title="%s"' % image.description)
                p.append('alt="%s"' % image.name)
                p.append('/>')                   
                t2.append(' '.join(p))
            else:
                t2.append(error)
        else:
            t2.append(i)
    return ''.join(t2)

然后在CustomFlatPage模型的save方法中使用上面的函数,像这样:

def save(self, *args, **kwargs):           
    self.content = process_image_tags(self.pre_content, ContentImage)        
    super(CustomFlatPage, self).save(*args, **kwargs)

它似乎有效,所以我可能最终会使用该解决方案。也许我会添加一些 javascript 让用户通过从生成的图像列表中选择图像来插入图像标签,但我认为即使现在它也比手动输入 url 要好。

【讨论】:

  • 我注意到您没有添加 alt 属性。你也可以使用image.name
  • @JordanReiter 是的,为什么不呢,谢谢 :-)。我只是将它添加到代码中。
猜你喜欢
  • 2011-03-24
  • 2013-08-15
  • 2019-08-08
  • 2017-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多