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

使用正则提取Scriban模板中{{}}包裹字段以验证动态对象

提取Scriban模板中的字段并验证动态对象

针对你用Scriban渲染HTML时需要提取模板字段、验证动态对象的需求,我给你整理了一套实用的方案:

1. 用正则表达式提取模板中的变量字段

Scriban模板里的变量都是用{{和}}包裹的,我们可以用非贪婪模式的正则来精准匹配这些内容。推荐的正则表达式是:

{{\s*(.+?)\s*}}

正则说明:

  • {{:精准匹配模板变量的开头标记
  • \s*:匹配变量前后的任意空白字符(包括空格、换行、制表符,兼容Scriban允许的格式)
  • (.+?):非贪婪匹配中间的字段内容,避免把多个变量(比如{{a}} {{b}})误匹配成一个整体
  • \s*:匹配结尾标记前的空白字符
  • }}:精准匹配模板变量的结尾标记

2. C# 代码示例(适配.NET环境)

假设你用的是C#,可以用Regex.Matches来提取所有匹配的字段,代码如下:

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

public class ScribanTemplateHelper
{
    public static IEnumerable<string> ExtractTemplateFields(string template)
    {
        var regex = new Regex(@"{{\s*(.+?)\s*}}", RegexOptions.Singleline);
        var matches = regex.Matches(template);
        
        foreach (Match match in matches)
        {
            // 取第一个捕获组的内容,就是我们需要的字段
            yield return match.Groups[1].Value.Trim();
        }
    }
}

// 测试你的示例模板
var sampleTemplate = @"<ul id='object'>
<h2>Name 2: {{ object.Username }}</h2>
<h1>Message 2: {{ object.Password }}</h1>
</ul>";

var fields = ScribanTemplateHelper.ExtractTemplateFields(sampleTemplate);
foreach (var field in fields)
{
    Console.WriteLine(field); // 输出:object.Username、object.Password
}

3. 验证动态对象是否包含所需字段

拿到字段集合后,你可以通过反射来验证动态对象的属性是否存在。如果你的动态对象是ExpandoObject,可以直接转换为IDictionary<string, object>来检查;如果是普通的匿名类型或动态实例,用反射处理:

针对ExpandoObject的验证:

using System.Dynamic;

public static bool ValidateDynamicObject(ExpandoObject dynamicObj, IEnumerable<string> requiredFields)
{
    var objDict = (IDictionary<string, object>)dynamicObj;
    foreach (var field in requiredFields)
    {
        // 处理嵌套字段,比如object.Username需要拆分层级
        var current = objDict;
        var parts = field.Split('.');
        bool exists = true;
        
        foreach (var part in parts)
        {
            if (!current.ContainsKey(part))
            {
                exists = false;
                break;
            }
            // 如果是嵌套的ExpandoObject,继续向下检查
            if (current[part] is ExpandoObject nestedObj)
            {
                current = (IDictionary<string, object>)nestedObj;
            }
            else
            {
                // 非嵌套字段,直接结束检查
                break;
            }
        }
        
        if (!exists)
        {
            Console.WriteLine($"缺失字段:{field}");
            return false;
        }
    }
    return true;
}

针对普通动态对象(反射方式):

public static bool ValidateDynamicObject(object dynamicObj, IEnumerable<string> requiredFields)
{
    var objType = dynamicObj.GetType();
    foreach (var field in requiredFields)
    {
        var parts = field.Split('.');
        var currentType = objType;
        object currentObj = dynamicObj;
        bool exists = true;
        
        foreach (var part in parts)
        {
            var property = currentType.GetProperty(part);
            if (property == null)
            {
                exists = false;
                break;
            }
            currentObj = property.GetValue(currentObj);
            currentType = property.PropertyType;
        }
        
        if (!exists)
        {
            Console.WriteLine($"缺失字段:{field}");
            return false;
        }
    }
    return true;
}

注意事项

  • 如果你的模板里包含Scriban的表达式(比如{{ if object.Age > 18 }}),这个正则也会提取出表达式内容。如果只需要提取单纯的变量字段,可以把正则调整为{{\s*([a-zA-Z0-9_.]+?)\s*}},限制只能匹配字母、数字、下划线和点号,过滤掉表达式语句。
  • 对于嵌套层级较深的字段,上面的验证代码已经处理了拆分检查的逻辑,能覆盖object.User.Name这类嵌套场景。

内容的提问来源于stack exchange,提问作者Bille

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:02:42