使用正则提取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
相关产品推荐
相关产品推荐

