C# - 在 string.Format 中自动检测转义和参数大括号
C# - Auto-detect Escape and Argument curly braces in string.Format
从此 C# 示例开始:
string myStringFormat = "I want to surround string {0} with {{ and }}";
string myStringArgs = "StringToSurround";
string myFinalString = string.Format(myStringFormat, myStringArgs);
我想知道是否有一种快速简单的方法来区分转义 character/sequence 和 curly braces/brackets 的参数。
我问这个问题的原因是:
+] 我想提供一些日志记录功能,我不想要求用户知道双卷曲 braces/brackets 转义规则
+] 我想快速区分性能需求
目前我能想到的唯一解决方案是扫描字符串寻找卷曲 braces/brackets 并对后续字符进行一些检查(数字解析)。正则表达式可能会有帮助,但我找不到在这种情况下使用它们的方法。
顺便说一句,我想要实现的最终情况是允许用户执行此操作而不会出现异常:
string myStringFormat = "I want to surround string {0} with { and }";
string myStringArgs = "StringToSurround";
//string myFinalString = string.Format(myStringFormat, myStringArgs); throwing exception
string myFinalString = MyCustomizedStringFormat(myStringFormat, myStringArgs);
编辑:
抱歉 "surround" 这个词很狡猾且具有误导性,请考虑这个例子:
string myStringFormat = "I want to append to string {0} these characters {{ and }}";
string myStringArgs = "StringToAppendTo";
string myFinalString = string.Format(myStringFormat, myStringArgs);
给出输出
我想追加到字符串 StringToAppendTo 这些字符 { 和 }
使用此正则表达式查找参数子字符串:
{\d+}
这个正则表达式转义{}
{1a}
等,只选择{1}
{11}
等
现在您需要处理 Arguments(用它们的值替换它们)或 Escaped 花括号(用双括号替换它们)。选择是你的,它取决于每个案例的出现次数。 (我选择替换下面代码中的参数)
现在您需要实际替换字符。同样,您可以选择是否使用 StringBuilder
。这取决于您输入的大小和替换的数量。无论如何我建议 StringBuilder
.
var m = Regex.Matches(input, @"{\d+}");
if (m.Any())
{
// before any arg
var sb = new StringBuilder(input.Substring(0, m[0].Index));
for (int i = 0; i < m.Count; i++)
{
// arg itself
sb.Append(args[i]);
// from right after arg
int start = m[i].Index + m[i].Value.Length;
if (i < m.Count - 1)
{
// until next arg
int length = m[i + 1].Index - start;
sb.Append(input.Substring(start, length));
}
else
// until end of input
sb.Append(input.Substring(start));
}
}
我相信这是最健壮和最干净的方法,而且它没有任何性能(内存或速度)问题。
编辑
如果您无权访问 args[]
那么您可以先将 {
/}
替换为 {{
/}}
然后简单地执行对代码的这些修改:
- 使用此模式:
@"{{\d+}}"
- 写
m[i].Value.Substring(1, m[i].Value.Length - 2)
而不是args[i]
从此 C# 示例开始:
string myStringFormat = "I want to surround string {0} with {{ and }}";
string myStringArgs = "StringToSurround";
string myFinalString = string.Format(myStringFormat, myStringArgs);
我想知道是否有一种快速简单的方法来区分转义 character/sequence 和 curly braces/brackets 的参数。
我问这个问题的原因是:
+] 我想提供一些日志记录功能,我不想要求用户知道双卷曲 braces/brackets 转义规则
+] 我想快速区分性能需求
目前我能想到的唯一解决方案是扫描字符串寻找卷曲 braces/brackets 并对后续字符进行一些检查(数字解析)。正则表达式可能会有帮助,但我找不到在这种情况下使用它们的方法。
顺便说一句,我想要实现的最终情况是允许用户执行此操作而不会出现异常:
string myStringFormat = "I want to surround string {0} with { and }";
string myStringArgs = "StringToSurround";
//string myFinalString = string.Format(myStringFormat, myStringArgs); throwing exception
string myFinalString = MyCustomizedStringFormat(myStringFormat, myStringArgs);
编辑:
抱歉 "surround" 这个词很狡猾且具有误导性,请考虑这个例子:
string myStringFormat = "I want to append to string {0} these characters {{ and }}";
string myStringArgs = "StringToAppendTo";
string myFinalString = string.Format(myStringFormat, myStringArgs);
给出输出
我想追加到字符串 StringToAppendTo 这些字符 { 和 }
使用此正则表达式查找参数子字符串:
{\d+}
这个正则表达式转义{}
{1a}
等,只选择{1}
{11}
等
现在您需要处理 Arguments(用它们的值替换它们)或 Escaped 花括号(用双括号替换它们)。选择是你的,它取决于每个案例的出现次数。 (我选择替换下面代码中的参数)
现在您需要实际替换字符。同样,您可以选择是否使用 StringBuilder
。这取决于您输入的大小和替换的数量。无论如何我建议 StringBuilder
.
var m = Regex.Matches(input, @"{\d+}");
if (m.Any())
{
// before any arg
var sb = new StringBuilder(input.Substring(0, m[0].Index));
for (int i = 0; i < m.Count; i++)
{
// arg itself
sb.Append(args[i]);
// from right after arg
int start = m[i].Index + m[i].Value.Length;
if (i < m.Count - 1)
{
// until next arg
int length = m[i + 1].Index - start;
sb.Append(input.Substring(start, length));
}
else
// until end of input
sb.Append(input.Substring(start));
}
}
我相信这是最健壮和最干净的方法,而且它没有任何性能(内存或速度)问题。
编辑
如果您无权访问 args[]
那么您可以先将 {
/}
替换为 {{
/}}
然后简单地执行对代码的这些修改:
- 使用此模式:
@"{{\d+}}"
- 写
m[i].Value.Substring(1, m[i].Value.Length - 2)
而不是args[i]