C# 字符串格式化大全

本文为译文,原文地址http://blog.stevex.net/string-formatting-in-csharp/,转载请注明来自本博客。

      关于在.NET中字符串格式化的方法String.Format(),本人一直找不到一本合适的快速参考,故作此文。

      自打本人学习.NET Framework起,心头一直纠结一件事。我找不到类似于C语言中的sprintf()的函数,它有一个输出缓冲,一个字符串的格式描述和一串参数,并且跟据这一切创建一串你需要的字符串。

      例如:

char szError[256];
sprintf(szError, "Error %d occurred.\n", nError);

      此句将生成一串“Error 12 occurred.” 到szError这个缓冲中(当然,前提是nError为12)。这是C语言编程的基础,甚至很多C++的程序员依然在使用这种方式,虽然在STL库中提供了更好的功能,但sprintf相对更加清晰而易于使用。

      STL中同样的做法会是:

str << "Error " << nError << " occurred." << endl;

      或者其它类似的方式。它虽然是类型安全的,而且比sprintf更面向对象,但比较难于阅读和本地化。

      .NET framework很好地处理了字符串--但这需要适应,在.NET中与sprintf最相近的就是静态方法String.Format(),它需要一个格式字符串和一些参数,然后生成一个输出的字符串。(相对于sprintf最大的闪光点在于你再也不用担心覆盖了输出缓冲。)

      例如:

string errorString = String.Format("Error {0} occurred.", nError);

      由于元数据机制的存在,.NET环境不需要格式字符串中指明要格式化的类型,你只要指明位置就行。(最常见的sprintf的Bug就是提供了错误的数据类型,在你误把%s当%d使用的时候,一但sprintf被调用,你的程序就会挂掉,没有任何保护。)

      在上面这个示例中,{0}将会被nError的值替换掉,但如果你想用指定的数值,或指定的进制(例如十六进制),.NET 都支持,但貌似这不是String.Format的功能,而是类型自己的功能。

      任何对象都有一个叫ToString()的方法来返回对象的字符串表述形式。ToString()方法可以接收一个告诉对象怎么来格式化自己的字符串参数,而在String.Format()中,这个格式字符串是在占位符后面传递,例如:"{0:##}"。

      花括号中的格式是这样的,{index[,alignment][:formatString]}。如果alignment是正数,文本在指定文本数的空间内右对齐;如果它是负数,则是左对齐。

字符串

      抱歉的是,对字符串真的没什么可格式化的,只有对齐,而且对齐对所有调用String.Format()中的内容都有效。

示例

输出
String.Format("->{0,10}<-", "Hello"); ->     Hello<-
String.Format("->{0,-10}<-", "Hello"); ->Hello     <-

 

数值

      内置的数值格式化主要包括如下内容:

识别符

类型 格式 输出(传值 Double 1.42) 输出(传值 Int -12400)

c

Currency {0:c} $1.42 -$12,400

d

Decimal {0:d} System.FormatException -12400

e

Scientific {0:e} 1.420000e+000 -1.240000e+004

f

Fixed point {0:f} 1.42 -12400.00

g

General {0:g} 1.42 -12400

n

带千分号的Number {0:n} 1.42 -12,400

r

四舍五入 {0:r} 1.42 System.FormatException

x

Hexadecimal {0:x4} System.FormatException cf90

      自定义数值格式化包括如下内容:

识别符

类型

格式

输出(传值 Double 1500.42)

注意

0

0占位符

{0:00.0000}

1500.4200

用0填充位置.

#

数字占位符

{0:(#).##}

(1500).42

 

.

小数点占位符

{0:0.0}

1500.4

 

,

千分号

{0:0,0}

1,500

必须在两个0中间

,.

数值缩放

{0:0,.}

2

缩小1000倍(整除)

%

百分号

{0:0%}

150042%

乘上100再加个%

e

指数占位符

{0:00e+0}

15e+2

允许多种指数格式

;

分组占位符

见文末示例

   

      分组占位符在处理货币型数据的时候非常有用,它可以用不同的格式显示负值或0,具体示例请看文末。

日期

      请注意日期的格式化依赖于计算机的地区设置;示例为本人的地区设置下的结果

识别符

类型

输出(传值 10/12/2002 10:11:29)

d 短日期 10/12/2002
D 长日期 December 10, 2002
t 短时间 10:11 PM
T 长时间 10:11:29 PM
f 完整日期和时间 December 10, 2002 10:11 PM
F 完整日期和时间(长) December 10, 2002 10:11:29 PM
g 默认日期和时间 10/12/2002 10:11 PM
G 默认日期和时间(长) 10/12/2002 10:11:29 PM
M 月和日 December 10
r RFC1123 日期时间 Tue, 10 Dec 2002 22:11:29 GMT
s 可排序的日期时间 2002-12-10T22:11:29
u 通用可排序本地日期时间 2002-12-10 22:11:29Z
U 通用可排序格林威治标准时间 December 10, 2002 10:11:29 PM
Y 年和月 December, 2002

      U 识别符貌似有问题,输出的字符串没有排序的意义。

      自定义日期时间格式化(以2002-12-10 10:11:29.932 PM为示例):

识别符

类型

示例

输出

dd {0:dd} 10
ddd {0:ddd} Tue
dddd 完整周名 {0:dddd} Tuesday
f, ff, … 秒的小数部分 {0:fff} 932
gg, … 纪元 {0:gg} A.D.
hh 2位数小时 {0:hh} 10
HH 2位数小时,24小时格式 {0:HH} 22
mm {0:mm} 11
MM {0:MM} 12
MMM 短月名 {0:MMM} Dec
MMMM 长月名 {0:MMMM} December
ss {0:ss} 29
tt 上下午 {0:tt} PM
yy 年,2位数 {0:yy} 02
yyyy {0:yyyy} 2002
zz 时区 {0:zz} -05:00
zzz 完整时区 {0:zzz} -05:00
: 分隔符 {0:hh:mm:ss} 10:11:29
/ 分隔符 {0:dd/MM/yyyy} 10/12/2002

 

枚举

识别符

类型

g

可以的话就显示名称,否则显示数值

f

显示名称

d

显示数值

x

八位十六进制

 

一些有用示例

      String.Format("{0:$#,###.00;¥#,###.00;零蛋}", value);

当传值1234.50的时候,输出是$1,234.50,当传值-1234.50的时候,输出是¥1,234.50,当传值0或-0的时候,输出是“零蛋” ,很显然,这很像C#中的三元表达式。

      String.Format(“{0:(###) ###-####}”, 8005551212);

输出是 “(800) 555-1212″。

posted @ 2010-07-20 21:07  Amo.Xu  阅读(2609)  评论(2编辑  收藏  举报