字符串.用大括号格式化
本文关键字:格式化 字符串 | 更新日期: 2023-09-27 18:14:31
我们的低级日志库必须处理发送给它的各种日志消息。
其中一些消息包含花括号(作为文本的一部分),有些消息包含要使用string格式化为字符串的一部分的参数。格式的
例如,这个字符串可以是Logger类的输入:
"参数:{主机名}值:{0}"使用发送给格式化程序使用的正确变量。
为了正确地完成它,我必须转义不属于格式的花括号(通过将它们加倍)。
我想用Regex来做,然而这并不像看起来那么简单,因为我不知道如何在花括号内匹配这些字符串(那些不被字符串使用的字符串)。用于格式化目的的格式)。
另一个问题是Logger类应该尽可能提高性能效率,开始处理正则表达式作为其操作的一部分可能会影响性能。
是否有适当的和已知的最佳实践?
在一个正则表达式中完成:
string input = "Parameter: {Hostname} Value: {0}";
input = Regex.Replace(input, @"{([^[0-9]+)}", @"{{$1}}");
Console.WriteLine(input);
输出:
参数:{{Hostname}}值:{0}
当然,这只适用于没有任何包含数字的参数,但仍然应该用{{ }}
我认为您应该查看您的日志记录器接口。比较Console.WriteLine
的工作方式:
-
Console.WriteLine(String)
完全输出给定的字符串,没有格式化,没有{和}的特殊。 -
Console.WriteLine(String, Object[])
使用格式化输出。{和}是特殊字符,调用方必须转义为{{和}}
我认为这是有缺陷的设计,必须区分不同的花括号出现在代码中,以找出其含义。将输出中应该出现的{转义为{{.
我会将所有的花括号翻倍,然后我会寻找那些被替换为像{{'d+}}
这样的正则表达式,这样它们就会回到原来的格式——{{0}}=>{0}——在你的字符串中。
因此,对于每一行,我将像这样做
string s = input.Replace("{", "{{").Replace("}", "}}");
return Regex.Replace(s, @"{{(?<val>'d+)}}",
m => { return "{" + m.Groups["val"] + "}"; }));
所以这是对最初问题的技术性回答,但是@Anders Abel是完全正确的。这个设计值得再考虑一下。
允许调用者使用格式化字符串并处理格式化说明符,例如
Logger.Log("{0:dd/mm/yyy} {0:hh:mm:ss} {hostname} {123Component}上发生{1:x4}错误",日期时间。UtcNow, 257)
你需要一个正则表达式:
string input = "{0:dd/mm/yyy} {0:hh:mm:ss} {hostname} Some error {1:x4} happened on {123Component}!";
Regex reg = new Regex(@"('{[^[0-9}]+?[^}]*'}|'{(?![0-9]+:)[^}]+?'})");
string output = reg.Replace(input, "{$1}");
Console.WriteLine(output);
这个输出:"{0:dd/mm/yyy} {0:hh:mm:ss} {{hostname}} Some error {1:x4} happened on {{123Component}}!"
但是重申一下,我同意Anders Abel的观点,您应该重新设计以避免需要日志库来做这些