您的位置:首页 > 移动开发 > Objective-C

.Net学习难点讨论系列6 - .Net中对字符串处理的方法

2011-05-24 21:03 459 查看
此文章在aierong
http://www.cnblogs.com/aierong/archive/2005/04/26/145617.html
基础上稍加改动。感谢原作者。

.Net提供了将数值、枚举或日期时间等数据类型表示为字符串的方法(依赖于给ToString()方法传入参数),也提供了(包括自定义解析过程)将字符串表示为某种类型的方法(类/对象名.Parse(string))。

格式化由格式说明符字符的字符串控制,该字符串指示如何表示基类型值;或者怎样将一个字符串解释为某个类型。

例如,格式说明符指示是否应该用科学记数法来表示格式化的数字;格式字符"C",表示货币格式等。(参考附录表格)

 

同时.NET Framework还使用区域性设置,以便用适合于特定区域性的形式表示基类型。

我们可以提供自定义的区域性设置,或者使用与当前线程关联的默认区域性设置。

例如,格式化货币类型的时候,区域性设置指定用于货币符号;格式化时间时根据区域设置来将一个字符串解释为DateTime型(DateTime.ParseExact()方法)。

 

本文主要介绍字符串格式控制

 

要是我们想拥有自己定义的格式化,.NET Framework也允许我们定义自己格式化方案和自定义区域性设置。例如:我想格式字符"MyFormat",来说明我自定义的格式,即在字符前加三个***,下文有代码示例。

 

关于数字格式字符串,可以参考类

System.Globalization.NumberFormatInfo

关于日期与时间格式字符串,可以参考类

System.Globalization.DateTimeFormatInfo

 

一个类要想实现格式化字符串输出需要实现Iformattable接口,先看看IFormattable

接口的原型:

public interface IFormattable

{

      // Methods

      string ToString(string format, IFormatProvider formatProvider);

}

参数说明:

format: 指定要使用的格式的 String,当为空引用时,表示使用为IFormattable实现的类型定义的默认格式。

formatProvider: 用于格式化该值的 IFormatProvider,当为空引用时,从操作系统的当前区域设置中获取格式信息的。

 

一些基本的值类型实现了该接口,例如: Int32 ,UInt32 , DateTime ,Guid ,类Enum。

 

其中的IFormatProvider

接口的原型

public interface IFormatProvider

{

      // Methods

      object GetFormat(Type formatType);

}

参数说明:

formatType: 一个对象,它指定要获取的格式对象的类型

 

NumberFormatInfo、DateTimeFormatInfo和CultureInfo实现IFormatProvider接口。

NumberFormatInfo: 提供数字格式信息,如用于小数分隔符和千位分隔符的字符,以及货币值中货币符号的拼写和位置。

DateTimeFormatInfo: 提供与日期相关和与时间相关的格式信息,如日期模式中月、日和年的位置。

CultureInfo: 包含特定区域性中的默认格式信息,其中包括数字格式信息以及与日期相关和与时间相关的格式信息。

再看看ICustomFormatter

接口的原型:

public interface ICustomFormatter

{

      // Methods

      string Format(string format, object arg, IFormatProvider formatProvider);

}

参数说明:

format: 包含格式规范的格式字符串。为空时 ,将使用默认格式规范。

arg: 要格式化的对象。其为空引用时,引发异常。

formatProvider : 一个IFormatProvider对象,它提供有关当前实例的格式信息。为空时,则忽略该参数。

 

代码示例:格式字符串"MyFormat",在字符前加三个***。

using
System;

 

public
class
MyClass
: System.IFormattable

{

Double
d;

 

public
MyClass(Double
d)

{

this
.d = d;

}

public
string
ToString(string
format, IFormatProvider
formatProvider)

{

return
(format == "MyFormat"
) ? "***"
+ d.ToString(formatProvider) : d.ToString(format, formatProvider);

}

}

 

class
Program

{

public
static
void
Main()

{

System.Globalization.CultureInfo
culture=null
;

 

MyClass
myClass = new
MyClass
(5);

//


IFormatProvider
为空时
,
调用的是当前线程关联的文化信息

Console
.WriteLine("

显示中国货币格式
:{0}"
, myClass.ToString("C"
, null
));

 

culture = System.Globalization.CultureInfo
.CurrentCulture;

Console
.WriteLine("

显示当前系统默认货币格式
:{0}"
, myClass.ToString("C"
, culture));

 

culture = new
System.Globalization.CultureInfo
("zh-HK"
);

Console
.WriteLine("

显示香港特别行政区货币格式
:{0}"
, myClass.ToString("C"
, culture));

 

Console
.WriteLine("

显示我自己定义的货币格式
:{0}"
, myClass.ToString("MyFormat"
, null
));

 

Console
.ReadLine();

}

}

输出结果:

显示中国货币格式:¥5.00

显示当前系统默认货币格式:¥5.0

显示香港特别行政区货币格式:HK$

显示我自己定义的货币格式:***5

以上示例中CultureInfo类的对象作为IFormatProvider类型的参数传入。自定义中调用了Double对象的ToString方法,因为Double对象也实现了IFormattable接口。

 

如果希望自定义格式化能在多个不同类使用,那么实现我们应该定义一个实现ICustomFormatter接口的类:

public
class
MyBaseFormat
: System.ICustomFormatter
, System.IFormatProvider

{

//

如果
format Type
与当前实例类型相同,则为当前实例,否则为空引用

public
object
GetFormat(Type
format)

{

if
(format == typeof
(ICustomFormatter
))

return
this
;

return
null
;

}

 

//

实现
Format
方法说明
:

//

如果您的格式方法不支持格式,则确定正在设置格式的对象是否实现
IFormattable
接口。

//

如果实现,请调用该接口的
IFormattable.ToString
方法。

//

否则,调用基础对象的默认
Object.ToString
方法。

public
string
Format(string
format, object
arg, IFormatProvider
provider)

{

if
(format == null
)

{

if
(arg is
IFormattable
)

return
((IFormattable
)arg).ToString(format, provider);

return
arg.ToString();

}

else

{

if
(format == "MyBaseFormat"
)

{

return
"***"
+ arg.ToString();

}

else

{

if
(arg is
IFormattable
)

return
((IFormattable
)arg).ToString(format, provider);

return
arg.ToString();

}

}

}

}

 

class
Program

{

public
static
void
Main()

{

string
printString = String
.Empty;

int
i = 100;

MyBaseFormat
myBaseFormat = new
MyBaseFormat
();

 

printString = string
.Format(myBaseFormat, "

显示正常格式
:{0}"
, i);

Console
.WriteLine(printString);

printString = string
.Format(myBaseFormat, "

显示正常格式
:{0:C}"
, i);

Console
.WriteLine(printString);

printString = string
.Format(myBaseFormat, "

显示自定义格式
{0:MyBaseFormat}"
, i);

Console
.WriteLine(printString);

 

Console
.ReadLine();

}

}

输出如下:

显示正常格式:100

显示正常格式:¥100.00

显示自定义格式***100

 

总结:

1.如果需要您自己的格式化包含在某个类上,在该类上实现IFormattable接口。

2.如果希望自定义格式化并使它可供多个不同类使用,那么实现 ICustomFormatter接口。

 

下面的函数是一个在网上找的的使用IFormattable的例子:

using
System;

 

///

<summary>

///
"

"
类的定义。

///

</summary>

public
class
Point
: System.IFormattable

{

///

<summary>

///

点类的横纵坐标。

///

</summary>

private
int
m_x, m_y;

 

public
Point(int
x, int
y)

{

m_x = x;

m_y = y;

}

#region
IFormattable
成员

///

<summary>

///

用于生成格式字符串的函数。

///

</summary>

///

<param name="format">

格式字符串。
</param>

///

<param name="formatProvider">

区域格式信息对象。
</param>

///

<returns></returns>

public
string
ToString(string
format, IFormatProvider
formatProvider)

{

string
retString;

try

{

//

判断格式字符串。

switch
(format.ToUpper())

{

case
"G"
: //

自定义的通用格式。

retString = string
.Format(formatProvider, "({0},{1})"
, m_x, m_y);

//"


"
对象的字符串格式为:
"(
十进制数字,十进制数字
)"


break
;

case
"S"
: //

自定义的标准格式。

retString = string
.Format(formatProvider, "<{0},{1}>"
, m_x, m_y);

//"


"
对象的字符串格式为:
"<
十进制数字,十进制数字
>"


break
;

default
: //

自定义的默认格式。

retString = string
.Format(formatProvider, "({0:X},{1:X})"
, m_x, m_y);

//"


"
对象的字符串格式为:
"(
十六进制数字,十六进制数字
)"


break
;

}

}

catch
(System.NullReferenceException
)

{

//

格式字符串为空,返回通用格式。

retString = string
.Format(formatProvider, "({0},{1})"
, m_x, m_y);

}

return
retString;

}

#endregion

}

///

<summary>

///
Test
的摘要说明。

///

</summary>

public
class
Test

{

public
static
void
Main()

{

//

定义一个点。

Point
p = new
Point
(13, 10);

//

打印默认格式的点。

Console
.WriteLine("{0}"
, p);

//

打印标准格式的点。

Console
.WriteLine("{0:S}"
, p);

/*

*
输出结果:
(13,10)

* <13,10>

*/

Console
.ReadLine();

}

}

 

注意:如果不实现IFormattable接口也可以用string.Format这些方法打印自定义类的对象,但string.Format方法只是调用object.ToString方法将类名打印出来。

下面是string.Format这些方法调用ToString的处理顺序:

1.如果要格式化的对象的值是 null,则返回空字符串 ("")。

2.如果要格式化的对象所属的类实现了 ICustomFormatter 接口,则调用ICustomFormatter.Format 方法。

3.如果前面的ICustomFormatter.Format 方法未调用,并且该类实现了 IFormattable 接口,则调用IFormattable.ToString 方法。

4.如果前面的步骤未格式化类型,则调用该类型的ToString方法(从 Object 类继承而来)。

然而,只有实现了IFormattable或ICustomFormatter这些接口才能识别我们自己定义的格式字符串,打印出我们想要的结果。

 

附录:

C#
格式化数值结果表

字符

说明

示例

输出

C

货币

string.Format
("{0:C3}", 2)


2.000

D

十进制

string.Format("{0:D3}", 2)

002

E

科学计数法

string.Format("{0:E}", 1.20E+001)

1.20E+001

G

常规

string.Format("{0:G}", 2)

2

N

用分号隔开的数字

string.Format("{0:N}", 250000)

250,000.00

X

十六进制

string.Format("{0:X000}", 12)

C

  string.Format("{0:000.000}", 12.2)

012.200

 

string.Format()
控制字符串缩进小技巧:

 

Sample

Generates

String.Format("->{1,10}<-", "Hello");

-> Hello<-

String.Format("->{1,-10}<-", "Hello");

->Hello <-

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息