解析/替换包含条件占位符的文本

huangapple go评论51阅读模式
英文:

Parse/Replace Text that contains conditional placeholders

问题

寻求一些关于此问题的建议或第三方库的知识。

对于用户生成的模板文本集,例如下面所示的内容,您将如何(尽可能自动地)进行解析和替换以获得逻辑输出呢?

总体概念是:用户将输入有关销售的信息到我的API中。然后,我需要将销售属性(名称、地址、购买物品的特征)合并到纯文本合同中。合同可以由用户编辑,他们有责任填充和维护。合同包含许多条件文本块,条件根据销售数据和合同用户的销售属性和条件的排列变化而满足/判断。

我已经构建了一些C#工厂,可以很好地工作。这些工厂使用正则表达式匹配和子字符串处理,但在每次迭代中,我发现越来越多的灵活性不足。例如,如果有一个预定义的占位符,如

{{if sale.type == abc}} 打印这个 {{else if sale.type == 123}} 打印那个 {{else}} 打印foo {{end}}

而用户决定不需要"else if",只需使用

{{if sale.type == abc}} 打印这个 {{else}} 打印foo {{end}}

正则表达式匹配、子字符串、分割等的组合开始崩溃。

此外,我正在考虑使用反射而不是预定义所有可能的销售属性条件。相反,我只会给用户一个属性名称列表,并允许他们基于销售的任何属性构建自己的条件占位符。

我想应该有模板引擎可以做到这一点,但我还没有找到一个是当前、相关或其他 - 但也许我遗漏了一些东西或对术语不了解。

理想情况下,我希望这个模板支持以下功能:

  • 基本的替换占位符
  • 条件分支(if/elseif/else,in/contains)
  • 条件嵌套
  • 要么可以直接使用,要么可扩展,以便我可以让具有中等能力的用户使用它。

感谢您的一切建议、评论和想法。

模板示例:

#1-基本占位符和if/else/end

嗨。今天是{{datetime}}。
{{if obj.isReady == true}} 我看到你准备好了。{{else}}很抱歉,你还没准备好。{{end}}

#2-包含if/in/else/end

{{if obj.Color IN [blue,red]}} 我也喜欢那个颜色。{{else}}嗯,不是我最喜欢的。{{end}}

#3-if/else if/else/end

{{if obj.Type == rock}} 滚动!{{else if obj.Type == paper}} 盖住!{{else}}剪,剪!{{end}}

#4-嵌套条件

{{if obj.Happy == true}} 很高兴你开心!{{if obj.Season == summer}}好温暖!{{else}} 哦!{{end}}{{else}}很抱歉,你不开心。{{end}}

英文:

Looking for a little advice or knowledge of 3rd party libraries that may help with this.

For a user-generated set of template text, such as those found below, how would you go about (automatically as possible) parsing and replacing to get the logical output?

The overall concept: the user will be inputting information about a sale into my API. I then need to mail merge the sale properties (name, address, features of what they bought) into a plain text, contract of sorts. The contract is user-editable, and their responsibility to populate and maintain. The contract has many conditional blocks of text, and the conditions are met/judged based on the sale's data, and the permutation of sale property and conditions vary by contract and user.

I've already built a couple C# factories for this that work fine. The factories use a combination of RegEx matching and good ol' substring and splitting, but with each iteration I'm finding more flexibility deficiencies. For example, if there's a predefined placeholder like

{{if sale.type == abc}} print this {{else if sale.type == 123}} print that {{else}} print foo {{end}}

and the user decides they don't need the "else if", remove it, and just use

{{if sale.type == abc}} print this {{else}} print foo {{end}}

the combination of RegEx matching, substring, splitting, etc starts falling apart.

Additionally, I'm considering using reflection instead of predefining all the possible conditions based on the properties of the sale. Instead, I'd just give the user a list of the property names, and allow them to construct their own conditional placeholders based on whatever property(s) of the sale they want.

I'd imagine that must be templating engines out there that can do this, but I've yet to run into one that is current, relevant, or otherwise - but maybe I'm missing something or ignorant of the terminology.

Ideally, I'd like this templating to support things like

  • basic, replace placeholders
  • conditional branching (if/elseif/else, in/contains)
  • nesting of conditions
  • either use to use out of the box, or extensible so that I have a user of moderate ability use it.

Thanks! Open to any/all suggestions, comments, and idea.

Template Examples:

#1-basic placeholder and an if/else/end

Hi. Today is {{datetime}}.
{{if obj.isReady == true}} I see you are ready. {{else}} I'm sorry you're not ready. {{end}}

#2-an if in/else/end

{{if obj.Color IN [blue,red]}} I love that color too. {{else}} Eh, not my favorite. {{end}}

#3-an if/else if/else/end

{{if obj.Type == rock}} ROLL! {{else if obj.Type == paper}} COVER! {{else}} SNIP, SNIP! {{end}}

#4-nested conditions
{{if obj.Happy == true}} Great you're happy! {{if obj.Season == summer}} So warm! {{else}} Burr! {{end}} {{else}} I'm sorry you're not happy. {{end}}

答案1

得分: 1

可以使用各种方法,其中之一是RazorEngine。

using RazorEngine;
using RazorEngine.Templating;
using System;
using System.Text.RegularExpressions;

class Program
{
    static void Main(string[] args)
    {
        var template = @"Hi. 今天是 @DateTime.Now。 @if (Model.IsReady) { <text>我看到你已经准备好了。</text> } else {<text>很抱歉,你还没准备好。</text>}";
        var model = new { IsReady = true };
        var result = Engine.Razor.RunCompile(template, "template", null, model);
        result = Regex.Replace(result, "<.*?>", string.Empty);
        Console.WriteLine(result);
    }
}

这个问题只是在RazorEngine期望HTML标签时需要规遍错误。不确定这是否也是最有效的方法。

链接

英文:

You can use various methods, one of them is RazorEngine.

using RazorEngine;
using RazorEngine.Templating;
using System;
using System.Text.RegularExpressions;

class Program
{
    static void Main(string[] args)
    {
        var template = @&quot;Hi. Today is @DateTime.Now. @if (Model.IsReady) { &lt;text&gt;I see you are ready.&lt;/text&gt; } else {&lt;text&gt;I&#39;m sorry you&#39;re not ready.&lt;/text&gt;}&quot;;
        var model = new { IsReady = true };
        var result = Engine.Razor.RunCompile(template, &quot;template&quot;, null, model);
		result = Regex.Replace(result, &quot;&lt;.*?&gt;&quot;, string.Empty);
        Console.WriteLine(result);
    }
}

The problem with this is just that you need to hack the errors when RazorEngine expects html tags. Not sure if this is the most efficient way also.

https://dotnetfiddle.net/MfTo8j

huangapple
  • 本文由 发表于 2023年4月7日 01:45:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/75952362.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定