如何替换字符串模板上的标记? [英] How to replace tokens on a string template?

查看:33
本文介绍了如何替换字符串模板上的标记?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习编写一个基本的模板引擎实现.例如我有一个字符串:

I'm attempting to learn to write a basic template engine implementation. For example I have a string:

string originalString = "The current Date is: {{Date}}, the time is: {{Time}}";

读取每个 {{}} 的内容然后用有效字符串替换整个标记的最佳方法是什么?

what is the best way of reading the contents of each {{}} and then replacing the whole token with the valid string?

感谢 BrunoLM 为我指明了正确的方向,到目前为止,这就是我所拥有的,它解析得很好,还有什么我可以做的事情来优化这个功能吗?

Thanks to BrunoLM for pointing me in the right direction, so far this is what I have and it parses just fine, is there any other things I can do to optimize this function?

private const string RegexIncludeBrackets = @"{{(.*?)}}";

public static string ParseString(string input)
{
    return Regex.Replace(input, RegexIncludeBrackets, match =>
    {
        string cleanedString = match.Value.Substring(2, match.Value.Length - 4).Replace(" ", String.Empty);
        switch (cleanedString)
        {
            case "Date":
                return DateTime.Now.ToString("yyyy/MM/d");
            case "Time":
                return DateTime.Now.ToString("HH:mm");
            case "DateTime":
                return DateTime.Now.ToString(CultureInfo.InvariantCulture);
            default:
                return match.Value;
        }
    });
}

推荐答案

简短回答

我认为最好使用正则表达式.

Short answer

I think it would be best to use a Regex.

var result = Regex.Replace(str, @"{{(?<Name>[^}]+)}}", m =>
{
    return m.Groups["Name"].Value; // Date, Time
});

<小时>

你可以使用:

string result = $"Time: {DateTime.Now}";

<小时>

String.Format &IFormattable

但是,已经有一种方法可以做到这一点.文档.

String.Format("The current Date is: {0}, the time is: {1}", date, time);

此外,您可以使用带有 IFormattable 的类.我没有进行性能测试,但这个测试可能很快:

And also, you can use a class with IFormattable. I didn't do performance tests but this one might be fast:

public class YourClass : IFormattable
{
    public string ToString(string format, IFormatProvider formatProvider)
    {
        if (format == "Date")
            return DateTime.Now.ToString("yyyy/MM/d");
        if (format == "Time")
            return DateTime.Now.ToString("HH:mm");
        if (format == "DateTime")
            return DateTime.Now.ToString(CultureInfo.InvariantCulture);

        return format;

        // or throw new NotSupportedException();
    }
}

并用作

String.Format("The current Date is: {0:Date}, the time is: {0:Time}", yourClass);

<小时>

检查您的代码和详细信息

在您当前使用的代码中


Review of your code and detailed information

In your current code you are using

// match.Value = {{Date}}
match.Value.Substring(2, match.Value.Length - 4).Replace(" ", String.Empty);

相反,如果你看我上面的代码,我使用了模式

Instead, if you look at my code above, I used the pattern

@"{{(?<Name>[^}]+)}}"

语法 (?.*) 表示这是一个 命名组,你可以在这里查看文档.

The syntax (?<SomeName>.*) means this is a named group, you can check the documentation here.

它允许您访问 match.Groups["SomeName"].Value 这将等同于该组的模式.所以它会匹配两次,返回日期"然后是时间",所以你不需要使用SubString.

It allows you to access match.Groups["SomeName"].Value which will be equivalent to the pattern with this group. So it would match two times, returning "Date" and then "Time", so you don't need to use SubString.

更新您的代码,这将是

private const string RegexIncludeBrackets = @"{{(?<Param>.*?)}}";

public static string ParseString(string input)
{
    return Regex.Replace(input, RegexIncludeBrackets, match =>
    {
        string cleanedString = match.Groups["Param"].Value.Replace(" ", String.Empty);
        switch (cleanedString)
        {
            case "Date":
                return DateTime.Now.ToString("yyyy/MM/d");
            case "Time":
                return DateTime.Now.ToString("HH:mm");
            case "DateTime":
                return DateTime.Now.ToString(CultureInfo.InvariantCulture);
            default:
                return match.Value;
        }
    });
}

为了进一步改进,您可以使用静态编译的 Regex 字段:

To improve even more, you can have a static compiled Regex field:

private static Regex RegexTemplate = new Regex(@"{{(?<Param>.*?)}}", RegexOptions.Compiled);

然后用作

RegexTemplate.Replace(str, match => ...);

这篇关于如何替换字符串模板上的标记?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆