如何使用string.Format()格式化花括号括起来的十六进制数?

13

输入: uint hex = 0xdeadbeef;

所需输出: string result = "{deadbeef}"

第一种方法: 显式地添加{}; 这种方法可行:

result = "{" + string.Format("{0:x}", hex) + "}"; // -> "{deadbeef}"

使用转义的花括号将输出转换为十进制而不是十六进制:

result = string.Format("{{{0}}}", hex); // -> "{3735928559}"

看起来很有前途,现在我们只需要按照上述第一种方法添加:x十六进制规范即可:

result = string.Format("{{{0:x}}}", hex); // -> "{x}"

哎呀,加上':x后它输出的是"{x}"而不是我想要的"{deadbeef}"

所以我的问题是:我是否必须像第一个示例那样显式添加{},或者有没有一种使用复合格式和转义花括号来解决它的方法?

还请注意,这也会影响字符串插值,因为(毕竟)它只是由编译器转换成对string.Format()的调用。

(这可能是重复的问题,但我迄今为止找不到重复的问题……)

编辑过


1
请参考 https://msdn.microsoft.com/zh-cn/library/txafckwd(v=vs.110).aspx 中的“转义括号”部分 - 基本上您的解决方法就是解决方案。 - Hans Kesting
这看起来像是 string.Format 中的一个错误。 - Lasse V. Karlsen
@HansKesting 那篇文章实际上就是这个问题的答案。如果你把它作为答案发布,我会标记它为正确的。 - Matthew Watson
1
我可以看到他们实际上将此记录为一个特性,而不是一个错误。然而,从某种意义上说,这确实是一个错误,因为如果你必须解释某些东西是如何破损的,那么它并不正确。但是,既然已经记录了这样的行为,你只需要绕过它即可。如果你按照这个解释的逻辑,那么 "{{{0}}}" 也不应该工作,因为 0} 不是一个有效的参数索引,但是既然它能够工作,那么就不一致了。 - Lasse V. Karlsen
这个答案也解决了这个问题({{{0:N}}}打印{N}). - CodeCaster
4个回答

7
请参阅http://msdn.microsoft.com/en-us/library/txafckwd(v=vs.110).aspx中的“转义括号”-基本上,您的解决方法是一个解决方案。从那里开始:转义大括号的解释可能会导致意外结果。例如,请考虑格式项 "{{{0:D}}}",它旨在显示一个左大括号,一个以十进制数格式化的数值,以及一个右大括号。但是,实际上,格式项的解释方式如下: 1.前两个左大括号("{{")被转义并产生一个左大括号。 2.接下来的三个字符("{0:")被解释为格式项的开头。 3.接下来的字符("D")将被解释为十进制标准数值格式说明符,但接下来的两个转义大括号("}}")将产生一个单个大括号。因为生成的字符串("D}")不是标准数值格式说明符,所以生成的字符串被解释为自定义格式字符串,表示显示文本字符串"D}"。 4.最后一个大括号("}")被解释为格式项的结尾。 5.显示的最终结果是文本字符串"{D}"。要格式化的数值未显示。作为解决方案,针对您的示例进行调整:
uint hex = 0xdeadbeef;
string output = string.Format("{0}{1:x}{2}", 
                             "{", hex, "}");
Console.WriteLine(output);

3
最接近的我得到的是
string.Format("{{{0:x}\u200B}}",16)

似乎 }}} 被错误解释了,插入一个零宽空格可以防止前两个 } 被展开为转义字符。


2
您可以使用空字符或添加括号作为参数:
uint hex = 0xdeadbeef;
string result = string.Format("{0}{1:x}{2}", "{", hex, "}");

这将按照您的要求输出 {deadbeef}

这是因为在 string.Format 中输出 } 时,您需要像这样转义它:}}

但是当您输入 }}} 时,它会将其理解为 }} } 并输出 {x}。这是 C# 中的设计错误,当您尝试格式化输出时,如 :x:N 等。

您也可以尝试

uint hex = 0xdeadbeef;
string result = string.Format("{{ {1:x} }}", hex);

然而这将输出带有空格的{ deadbeef }


1
这是string.Format中的一个bug,不是C#的问题。 - Lasse V. Karlsen
@LasseV.Karlsen 有什么显著的区别吗? - cat
请看我对问题的评论。 - Lasse V. Karlsen

2
尝试这样做:使用两次String.Format方法,像这样:
String result= String.Format("{{{0}}}",String.Format("{0:x}", hex));

不需要格式化参数,你可以使用 hex.ToString("x") - CodeCaster
@CodeCaster,OP想要将这个十六进制字符串包装在花括号中{deadbeef} - Jaydip Jadhav
你没有理解重点。可以使用hex.ToString("x")来代替String.Format("{0:x}", hex) - CodeCaster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接