You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何根据Jinja2模板字段的位置渲染出大小写正确的内容?

如何根据Jinja2模板字段的位置渲染出大小写正确的内容?

嘿,我明白你想要实现的效果——同一个字段在句子开头要大写,在句子中间就保持小写,但之前的方法为啥不管用呢?问题出在你的自定义过滤器上:它是全局检查整个模板有没有字段出现在句首,然后直接返回统一的大写或小写结果,这就导致所有地方的字段都会变成一样的,完全没区分每个字段的具体位置。

那怎么解决这个问题?其实咱们可以换个思路:先把所有字段都渲染成小写,然后再对渲染后的HTML做针对性替换,把那些位于句子开头的字段改成首字母大写。这样就能精准处理每个位置的情况了,具体步骤和代码如下:

解决方案代码

from jinja2 import Environment, from_string
import re

# 你的模板内容
EXAMPLE_BODY_1 = """
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Example</title>
  </head>
  <body>
    <div><h2>Example Contract Term</h2></div>
    <div>
      <p>
        Sometimes the example_field is in the middle so needs to be lowercase,
        {{ example_field }} is a good example.
      </p>
      <ul>
        <i>All terms in this example are binding.</i>
        <i>The terms are made up as this is an example.</i>
        <i>Terms can always change.</i>
      </ul>
    </div>

    <div><h2>Example Contract Other Term</h2></div>
    <div>
      <p>
        {{ example_field }} can also be at the start of a sentence to therefore
        needs to be capitalised.
      </p>
      <ul>
        <i>Sometimes it's like the first example.</i>
        <i>The terms are made up as this is an example.</i>
        <i>Terms can always change.</i>
      </ul>
    </div>
  </body>
</html>
"""

# 初始化Jinja环境并加载模板
environment = Environment()
template = environment.from_string(EXAMPLE_BODY_1)
example_merge_field = "pots and pans"

# 第一步:先把所有字段渲染成小写版本
rendered_html = template.render(example_field=example_merge_field.lower())

# 第二步:定义要替换的目标字符串
target_lower = example_merge_field.lower()
target_capitalized = example_merge_field.capitalize()

# 正则匹配两种句子开头的情况:
# 1. <p>标签后紧跟的内容(可能带空格)
# 2. 句子结束标点(.?!)后紧跟的内容(可能带空格)
pattern = re.compile(r'(<p>\s*|\.|\?|!)\s*' + re.escape(target_lower))

# 定义替换规则
def replace_match(match):
    prefix = match.group(1)
    # 如果是<p>标签开头,直接拼接大写后的内容;如果是标点,要加个空格
    if prefix == '<p>':
        return f"{prefix}{target_capitalized}"
    else:
        return f"{prefix} {target_capitalized}"

# 执行替换得到最终HTML
final_html = pattern.sub(replace_match, rendered_html)

print(final_html)

为什么这个方法管用?

  1. 先统一渲染成小写,确保句子中间的字段符合要求;
  2. 用正则精准定位那些位于句子开头的字段:包括段落开头、以及标点后的句子开头;
  3. 只把这些定位到的字段替换成首字母大写版本,完美区分不同位置的需求。

如果你想用更“原生”的Jinja方式处理,其实也可以给每个字段调用不同的过滤器(句首用{{ example_field|capitalize }},句中用{{ example_field|lower }}),但这种方法需要手动修改模板里的每个字段位置,不如上面的自动替换方法灵活。

备注:内容来源于stack exchange,提问作者Johnny John Boy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 15:38:11