【问题标题】:String Formatting in a .NET Templating Engine (ideally Nustache).NET 模板引擎中的字符串格式化(最好是 Nustache)
【发布时间】:2014-04-24 20:52:57
【问题描述】:

我正在编写一个需要使用 HTML 文件作为模板的报告系统。我正在考虑使用Nustache 来处理它,因为它看起来很理想且非常轻量级。我遇到的唯一问题是我需要能够在数字数据绑定项中指定特定的小数位数。

我知道我可以在数据源中有一个访问器属性,它在内部执行 String.Format,然后返回一个表示数字的格式化字符串。这样做的问题是模板本身无法指定格式(例如小数位数)。

有没有办法从模板本身指定小数位?因为我真的很喜欢 Nustache,所以我正在考虑编写一些在处理格式之前和之后处理模板文件的东西。但是想检查一下,如果这已经被支持,我没有重新发明轮子,而且我只是错过了一些现有的功能。

我在想的是,如果在允许 Nustache 执行此操作之前,预处理过程是否将 {{MyNumber|3}} 替换为 <$$${{MyNumber}}|3$$$>。其中 3 是小数位数。所以它看起来像<$$$123|3$$$>。然后在 Nustache 处理完之后,我会有一个使用正则表达式来提取 Nustache 插入的数字和 3 的后处理,然后进行字符串格式化和替换。请注意,<$$$$$$> 只是组成字符串,用于指示后期处理需要处理的块的开始和结束。

在我的情况下,我只需要它来指定小数位,所以我可以安全地假设其中包含 {{x|y}} 的任何内容都是十进制值,其中 y 表示小数位数地方。

我这样做是在重新发明轮子吗?还有其他想法吗?或者这个解决方案有问题?

【问题讨论】:

  • 您的问题与 StackOverflow 无关。为什么不直接使用T4
  • 为什么跑题了?阅读帮助中心文章,我觉得它很切题。感谢 T4 的建议——我会阅读一下它。我以前听说过这个名字,但还不知道。
  • 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,请描述问题以及迄今为止为解决该问题所做的工作。我没有制定 SO 规则,但很抱歉
  • 很公平 - 我没有看到那一点 - 我只是查看了我认为我的问题匹配的项目符号列表。希望在它关闭之前我能得到一些建议;)将检查 T4 - 感谢您的指点。
  • 我已经重写了这个问题,希望它现在符合要求。在其中,我想我可能已经回答了我自己的问题,但看看人们对解决方案的看法会很有趣。

标签: c# .net template-engine


【解决方案1】:

我实际上已经实施了我的建议,因为它根本不需要很长时间。似乎工作得很好。它目前是有限的,因为它假定{{x|y}} 使用 x 作为十进制类型, y 作为十进制字符数。我还使用了<######>,因为在正则表达式替换字符串中使用了$(例如,$1 是第一个匹配的组,等等)。所以使用# 意味着我不必逃避它们。

如果有人感兴趣,代码如下:

using System.Text.RegularExpressions;

public static class NustacheUtil
{
    public static string PreProcess(string templateString)
    {
        return Regex.Replace(templateString, @"{{(.*?)\|(\d+)}}", @"<###{{$1}}|$2###>");
    }

    public static string PostProcess(string templateString)
    {
        var result = templateString;

        for(;;)
        {
            var match = Regex.Match(result, @"<###([0-9.]+?)\|(\d+)###>");

            if(!match.Success || match.Groups.Count != 3)
            {
                break;
            }

            decimal value;

            if(decimal.TryParse(match.Groups[1].Value, out value))
            {
                var numDecimalPlaces = match.Groups[2].Value;
                result = result.Remove(match.Index, match.Length);
                result = result.Insert(match.Index, value.ToString("N" + numDecimalPlaces));
            }
        }

        return result;
    }
}

还有一些测试:

using NUnit.Framework;

[TestFixture]
class NustacheUtilTests
{
    [Test]
    public void PreProcessTest_Single()
    {
        // Arrange
        const string templateString = "Test number: {{MyNumber|3}}";

        // Act
        var result = NustacheUtil.PreProcess(templateString);

        // Assert
        Assert.That(result, Is.EqualTo("Test number: <###{{MyNumber}}|3###>"));
    }

    [Test]
    public void PostProcessTest_Single()
    {
        // Arrange
        const string templateString = "Test number: <###123.456789|3###>";

        // Act
        var result = NustacheUtil.PostProcess(templateString);

        // Assert
        Assert.That(result, Is.EqualTo("Test number: 123.457"));
    }

    [Test]
    public void PreProcessTest_Multiple()
    {
        // Arrange
        const string templateString = "Test number: {{MyNumber|3}}, and another: {{OtherNumber|2}}";

        // Act
        var result = NustacheUtil.PreProcess(templateString);

        // Assert
        Assert.That(result, Is.EqualTo("Test number: <###{{MyNumber}}|3###>, and another: <###{{OtherNumber}}|2###>"));
    }

    [Test]
    public void PostProcessTest_Multiple()
    {
        // Arrange
        const string templateString = "Test number: <###123.457|3###>, and another: <###947.74933|2###>";

        // Act
        var result = NustacheUtil.PostProcess(templateString);

        // Assert
        Assert.That(result, Is.EqualTo("Test number: 123.457, and another: 947.75"));
    }
}

和 Nustache 的用法:

var templateString = NustacheUtil.PreProcess(templateString);
templateString = Render.StringToString(templateString, dataSource);
templateString = NustacheUtil.PostProcess(templateString);

它显然还没有被用于愤怒。当我进行更改时,我会在此处更新代码,因为我确信我会在我正确使用它时进行改进。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    相关资源
    最近更新 更多