替换Python字符串中的自定义“HTML”标记

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (123)

我希望能够在字符串中包含自定义“HTML”标记,例如:"This is a <photo id="4" /> string"

在这种情况下,自定义标签是<photo id="4" />。我也可以将这个自定义标签改为不同,如果它使它更容易,即[photo id:4]什么的。

我希望能够将此字符串传递给将提取标记的函数<photo id="4" />,并允许我将其转换为更复杂的模板<div class="photo"><img src="...." alt="..."></div>,然后我可以使用它来替换原始字符串中的标记。

我正在成像这样的工作:

>>> content = "This is a <photo id="4" /> string"
# Pass the string to a function that returns all the tags with the given name.
>>> tags = parse_tags('photo', string)
>>> print(tags)
[{'tag': 'photo', 'id': 4, 'raw': '<photo id="4" />'}]
# Now that I know I need to render a photo with ID 4, so I can pass that to some sort of template thing
>>> rendered = render_photo(id=tags[0]['id'])
>>> print(rendered)
<div class="photo"><img src="...." alt="..."></div>
>>> content = content.replace(tags[0]['raw'], rendered)
>>> print(content)
This is a <div class="photo"><img src="...." alt="..."></div> string

我认为这是一个相当常见的模式,比如把照片放在博客文章中,所以我想知道是否有一个库会做类似于parse_tags上面的示例函数的库。或者我需要写它吗?

这个照片标签的例子只是一个例子。我想要有不同名称的标签。作为一个不同的例子,也许我有一个人的数据库,我想要一个标签<person name="John Doe" />。在那种情况下,我想要的输出是类似的{'tag': 'person', 'name': 'John Doe', 'raw': '<person name="John Doe" />'}。然后我可以使用该名称查看该人并返回该人的vcard或其他东西的渲染模板。

提问于
用户回答回答于

如果您正在使用HTML5,我建议您查看xml模块(etree)。它将允许您将整个文档解析为树结构并单独操作标记(然后将resut bask转换为html文档)。

您还可以使用正则表达式来执行文本替换。如果您没有太多的更改,这可能比加载xml树结构更快。

    import re
    text = """<html><body>some text <photo> and tags <photo id="4"> more text <person name="John Doe"> yet more text"""
    tags = ["photo","person","abc"]
    patterns = "|".join([ f"(<{tag} .*?>)|(<{tag}>)" for tag in tags ])
    matches = list(re.finditer(patterns,text))
    for match in reversed(matches):
        tag = text[match.start():match.end()]
        print(match.start(),match.end(),tag)
        # substitute what you need for that tag
        text = text[:match.start()] + "***" + text[match.end():]
    print(text)

这将打印出来:

    64 88 <person name="John Doe">
    39 53 <photo id="4">
    22 29 <photo>
    <html><body>some text *** and tags *** more text *** yet more text

以相反的顺序执行替换可确保finditer()找到的范围保持有效,因为文本随替换而变化。

扫码关注云+社区

领取腾讯云代金券