- 浏览: 243991 次
- 性别:
- 来自: 葡萄牙
文章分类
最新评论
-
lightbulb:
...
jQuery中的动画与效果 -
kendezhu:
<div class="quote_title ...
jQuery 获取和设置select下拉框的值 -
opportunity:
谢谢kendezhu分享,今天正好用上了!
jQuery 获取和设置select下拉框的值
字符、字符串和文本处理
- 博客分类:
- CLR
字符
http://www.cnblogs.com/bitfan/archive/2010/11/25/1887590.html
在.NET Framework中,字符都是用16位unicode编码(utf-16)【视频 unicode字符编码查询(它这个编码方式是utf-16的Big Endian,具体可看最上面的链接) unicode字符编码表(十进制0~127是与ASCII字符集(占7位)的一样(写的时候十六进制前面加0x就是0x0(0)~0x7F(127)) 十进制19968~40895 CJK统一表意符号是主要的中文)】的(编译时用utf-16编码成2进制存到硬盘,程序运行时再用utf-16解码显示 代码中的字符串,在内存中相应的字节流就是用UTF-16编码过的 相关① ②),也就是说所有字符都是占2个字节16位,这简化了国际化应用程序的开发。
unicode字符集有很多种编码方案,常用的有
utf-16:所有字符被编码成2个字节
utf-8:十进制小于128的字符被编码成1个字节(可表示欧美地区使用的字符),128~2047的字符被编码成2个字节(可表示欧洲和中东语言),大于2047的字符被编码成3个字节(可表示东亚地区的语言)
utf-32:所有字符都被编码成4个字节
unicode字符集还有个ASCII编码方案,这种编码只能将小于128的16位字符转换成单字节,而其他超过127的字符都会丢失。
GB2312等其他字符集(这些字符集可能只有一种同名编码方案)
可以调用Char类型的静态方法GetUnicodeCategory方法,这个方法返回的是System.Globalization.UnicodeCategory枚举类型的一个值。这个值指出该字符是控制字符、货币符号、小写字母、大写字母、标点符号、数字符号 还是其他Unicode标准定义的符号。 其他一些静态方法如IsDigit、IsLetter、IsUpper、IsControl、IsSymol等都在内部调用了GetUnicodeCategory,并简单返回true或false。
可以调用静态方法ToLowerInvariant或者ToUpperInvariant以一种忽略语言文化的方式,将一个字符转化为小写或大写。如果调用ToLower和ToUpper方法,在转换时要使用与线程相关的语言文化信息,这俩方法会在内部查询System.Threading.Thread类的静态CurrentCulture属性来获得的。还可以向这俩方法传递CultureInfo类的一个实例来具体指定一种语言文化。
System.String类型
一个String代表一个不可变的顺序字符集。String类型直接派生自Object,所以它是一个引用类型。因此String对象总是存在于堆上,永远不会跑到线程栈。许多编程语言都将String视为一个基元类型----可以再源代码中直接表示string s="hi"; 编译器将这些文本常量字符串放到模块的元数据中,并在运行时加载和引用它们。
对于换行符、回车符和退格符这样的特殊字符,C#采用的是C/C++开发人员熟悉的转义机制:
string s="hi\r\nthere"; 包含回车符和换行符
string s="hi"+Environment.NewLine+"there";
对于如下由好几个文本常量字符串组成的字符串:
string s="hi"+" "+"there"; 编译器会在编译时连接它们,最终只会将一个字符串放到模块的元数据中。
对于如下由好几个非文本常量字符串组成的字符串:
string s1="hi"; string s2="there"; string s=s1+s2; 这些字符串的连接会在运行时进行,这会在堆上创建多个字符串对象。
C#还提供了逐字字符串,通常用于指定文件或目录的路径,或与正则表达式配合使用:
string file="C:\\windows\\System32\\Notepad.exe";
string file=@"C:\windows\System32\Notepad.exe";
在字符串前添加@符号,使编译器知道字符串是一个逐字字符串,这告诉编译器将反斜杠视为文本常量,而不是转义符。
string对象最重要的一个事实就是,它是不可变的,也就是说字符串一经创建便不能更改,不能变长,变短或修改其中任何字符。
所以允许对一个字符串进行各种操作而不实质的改变字符串:
string s="hiworld"; if(s.ToUperInvariant().Substring(0,2).EndsWith("EXE")){...}
在此,ToUperInvariant()返回一个新的字符串,它没有修改s的字符,然后Substring(0,2)在ToUperInvariant()返回的新字符串的基础上又返回一个新字符串。 ToUperInvariant和Substring创建的两个临时字符串不会由应用程序代码长久的引用,垃圾回收器会在下次回收时回收它们的内存,如果执行大量的字符串操作,会在堆上创建大量的string对象,造成频繁的垃圾回收。
使字符串不可变,还意味着在操纵或访问一个字符串时不会发生线程同步问题。
比较字符串
.NET Framework使用System.Globalization.CultureInfo类型表示一个“语言/国家”对。如:en-US代表美国英语,en-AU代表澳大利亚英语,de-DE代表德国德语。
在CLR中,每个线程都关联了两个特殊属性,每个属性都引用一个CultureInfo对象:
CurrentUICulture属性:该属性用于获取要向用户显示的资源,当创建一个线程时,这个线程属性会被设置成一个CultureInfo对象,它标示了正在运行应用程序的windows的版本所用的语言,该语言是使用Win32的函数GetUserDefaultUILanguage来获取的,可通过控制面板的“区域和语言”对话框来设置。
CurrentCulture属性:该属性用于数字和日期格式化、字符串大小写以及字符串比较。
一般而言这俩属性被设为同一CultureInfo对象,即它们使用相同的语言/国家信息。然而,比如我们在美国运行一个应用程序需要用西班牙语来显示菜单及其他GUI元素,同时仍要正确显示美国的货币和日期格式。为此,线程的CurrentUICulture属性要引用一个CultureInfo对象,该对象要使用语言“es”来初始化。线程的CurrentCulture属性要引用另一个CultureInfo对象,该对象应使用“en-US”来初始化。
CultureInfo ci1=new CultureInfo("es"); CultureInfo ci1=new CultureInfo("en-US");
高效率构造字符串
从逻辑上讲StringBuilder对象包含一个字段,该字段引用了由Char结构构成的一个数组。可利用StringBuilder的各个成员来操纵这个字符数组,高效率地缩短字符串或更改字符串中的字符。如果字符串变大,超过了已分配的字符数组的大小,StringBuilder会自动分配一个新的、更大的数组,复制字符,并开始使用新数组。前一个数组会被垃圾回收。
StringBuilder有两值的一提的构造函数来设置其属性:1是最大容量(设置返回字符串toString()所能容纳的最大字符数,默认是Int32.MaxValue约为20亿,一般不需要修改)2是容量(由StringBuilder维护的字符数组的大小,默认是16,上面提到了超过了已分配的字符数组的大小会自动倍增分配一个更大的数组,原数组会被垃圾回收,这影响性能,所以一开始需设置一个合适大小的容量)
获取对象的字符串表示:ToString
System.Object实现的ToString只是返回对象所属类型的全名。这个值用处不大,但对许多不能提供有意义的字符串的类型来说,这也是一个合理的默认值。例如,一个FileStream或Hashtable对象的字符串表示应该是什么呢?
任何类型如果想提供一个合理的方式获取对象当前值的字符串表示,应该重写ToString方法。FCL内建的所有基类型都重写了它们的ToString方法,能返回一个符合语言文化的字符串。在Vistual Studio调试器中,鼠标移到一个变量上方,就会显示一条数据提示,提示的文本就是通过调用对象的ToString方法获取的。所以,在定义一个类时,可以重写ToString方法,以获得良好的调试支持。
指定具体的格式和语言文化
无参的ToString方法有两个问题,首先,调用者无法控制字符串的格式,其次,调用者不能方便的调用一种特定的语言文化。
为了使调用者能选择格式和语言文化,类型应该实现System.IFormattable接口:
public interface IFormattable{
String ToString(String format,IFormatProvider formatprovider)
}
第一个参数format是一个特殊的字符串,作用是告诉方法该如何格式化对象,假如传递的格式化字符串无法被类型识别,类型应该抛出System.FormatException异常。 第二个参数formatprovider是实现了System.IFormatProvider接口的类型的实例,System.Globalization.CultureInfo类型就实现了它,用于指定具体的语言文化。
在FCL中,所有基类型都实现了 IFormattable接口,枚举类型都自动实现 IFormattable接口。
FCL中许多类型都能同时识别几种格式:
DateTime -> d短日期 D长日期 g表示常规 M月/日 s表示可排序(sortable) T长时间 u表示符合ISO 8601格式的协调世界时 U长日期格式的协调世界时 Y年/月
枚举类型 -> G表示常规 F标识(flag) D十进制 X十六进制
数值类型 -> C货币类型 D十进制 E表示科学技术法(指数)格式 F定点(fix-point)格式 G表示常规 N数字格式 P百分比格式 R往返行程格式 X十六进制
以下代码将以越南地区适用的货币格式来获取一个Decimal数值的字符串表示:
Decimal price=123.5M;
String s=price.ToString("C",new CultureInfo("vi-VN"));
如果不向ToString()传递参数或传递null ToString(null,null) 将默认是选择了常规格式 和 当前线程的语言文化。
将多个对象格式化成一个字符串
String s=String.Format(“On {0}, {1} is {2} years old”,new DateTime(2010,4,22,14,35,5),"Bill",7);
On 2010-4-22 14:35:05, Bill is 7 years old
在内部,Format方法会调用每个对象的ToString方法来获取对象的一个字符串表示。
String s=String.Format(“On {0:D}, {1} is {2:E} years old”,new DateTime(2010,4,22,14,35,5),"Bill",7);
On 2010年4月22日, Bill is 7.000000E+000 years old
采取在大括号内指定格式信息的方式,可对一个对象的格式化进行更多控制。
String类的静态Format方法的几个重载版本。一个版本实现了IFormatProvider接口的一个对象,允许使用由调用者指定的语言文化信息来格式化所有可替换的参数。
提供定制格式化器
我们可以定义一个方法,以便在任何对象需要格式化成一个字符串时,由String的Format方法来调用这个方法。也就是说,Format方法不是调用每个对象的ToString,而是调用我们自己定义的方法,从而按照我们自己希望的任何方式格式化部分或全部对象。它也同样适用于StringBulider的AppendFormat方法:
protected void Page_Load(object sender, EventArgs e)
{
Label1.Text = string.Format(new BoldInt(), "{0} {1} {2}", "I am", 17, "years old.");
}
internal class BoldInt : IFormatProvider, ICustomFormatter
{
public object GetFormat(Type formatType)
{
if (formatType==typeof(ICustomFormatter))
{
return this;
}
return Thread.CurrentThread.CurrentUICulture.GetFormat(formatType);
}
public string Format(string format,object arg,IFormatProvider formatprovider)
{
string s;
IFormattable formattable = arg as IFormattable;
if (formattable == null)
{
s = arg.ToString();
}else {
s = formattable.ToString(format, formatprovider);
if (arg.GetType()==typeof(int))
{
return "<B style='color:red'>" + s + "</B>";
}
}
return s;
}
}
以上在Format方法(这是实现了ICustomFrmat接口里的Format方法)内部,进行了一些巧妙的操作,从而对字符串的格式化进行全面的控制。
解析字符串来获取对象:Parse
能解析一个字符串的任何类型都提供了一个名为Parse的public static方法。该方法获取一个string对象,并返回类型的一个实例。从某种意义上说,Parse扮演了工厂的角色。在FCL中,所有数值类型、DateTime、TimeSpan以及其他一些类型(比如SQL数据类型)均提供了Parse方法。
Parse方法有很多重载,最全的一种如下:
public static Int32 Parse(String s,NumberStyles style,IFormatProvider provider)
s就是要解析的字符串,System.Globalization.NumberStyles是一个枚举类型,IFormatProvider就是语言文化方面的
Int32 x=Int32.Parse(" 123",NumberStyle.None,null); 会抛出一个System.FormatExcept异常
如果要允许Parse跳过前导的空白字符,要像下面这样修改style参数:
Int32 x=Int32.Parse(" 123",NumberStyle.AllowLeadingWhite,null);
如何解析一个十六进制数字:
Int32 x=Int32.Parse("1A",NumberStyle.HexNumber,null); 26
DateTime类型提供的Parse方法的style参数是System.GlobalizationDateTimeStyles枚举类型
一些开发人员反映当他们的应用程序频繁调用Parse,而且Parse频繁抛出异常时(由于无效的用户输入)应用程序的性能显著下降,为此微软将提供Parse方法的类型,甚至IPAddress类型都增加了TryParse方法:
public static Boolean TryParse(String s,NumberStyles style,IFormatProvider provider,out Int32 result)
可以看出,这个方法返回true或false,指出传递的字符串是否能解析成一个Int32,如果返回true,以"传引用"的方式给result参数的变量将包含解析好的数值。
字符和字节的相互转换
在CLR中所有字符都是以16位Unicode码值的形式来表示的,当我们需要将一个字符串保存到文件中或者通过网络来传输它们,我们可以将16位值编码成一个压缩的字节数组,以后再将字节数组解码回一个16位值数组。
需要编码或解码一组字符的时,应获取从System.Text.Encoding派生的一个类的实例。Encoding是一个抽象基类,它提供了几个静态readonly属性(UTF8,Unicode[UTF-16],BigEndianUnicode,UTF32,UTF7,ASCII,Default),每个属性都返回从Encoding派生的一个类的实例,它决定应该用哪种方式编码/解码字符:
String s="Hi there";
Byte[] encodeBytes=Encoding.UTF8.GetBytes(s); 用utf-8编码字符
BitConvert.ToString(encodeBytes); 显示编码的字节值 46-69-20-74-68-65-72-65-2E
String decodeString=Encoding.UTF8.GetString(encodeBytes); 用utf-8解码字符
上面我们看到了写了两次Encoding.UTF8,但CLR会给我们优化,只会实例化一个实例,而实现同样的效果,可以实例化System.Text.UTF8Encoding,System.Text.UnicodeEncoding等,实例化几次就创建几个对象,会损坏性能。
Encoding还提供了一个静态的GetEncoding方法,它返回一个可以使用指定代码页进行编码或解码的对象,如Encoding.GetEncoding(“Shift-JIS”)或Encoding.GetEncoding(932)
当从一个流中读取字节时,使用上面对象的GetString方法有可能造成数据损坏,这是因为Encoding派生的所有类都不对多个方法调用之间的状态进行维护。可以使用Encoding.UTF8.GetEncoder(),Encoding.UTF8.GetDecoder()方法得到的对象来对字节块进行编码,解码:
http://technet.microsoft.com/zh-cn/library/system.text.utf8encoding.getencoder(VS.95).aspx
http://technet.microsoft.com/zh-cn/library/system.text.utf8encoding.getdecoder(VS.95).aspx
string s = "家里都有两条龙";
char[] chars=s.ToCharArray();
int bytelength = Encoding.UTF8.GetEncoder().GetByteCount(chars, 0, chars.Length, true);
byte[] bytes = new byte[bytelength];
Encoding.UTF8.GetEncoder().GetBytes(chars, 0, chars.Length, bytes, 0,true);
Label4.Text += BitConverter.ToString(bytes);
int charlength = Encoding.UTF8.GetDecoder().GetCharCount(bytes, 0, bytes.Length);
char[] chars = new char[charlength];
Encoding.UTF8.GetDecoder().GetChars(bytes,0,bytes.Length,chars,0);
foreach (char c in chars)
{
Label3.Text += c.ToString();
}
Base-64字符串的编码和解码
byte[] byte=new byte[10];
new Random().NextBytes(byte); 随机产生10个随机byte的数组
Label5.Text = Convert.ToBase64String(byte); 参数只能是byte[]
byte[] base64byte=Convert.FromBase64String(Label5.Text); 参数只能是base64格式的字符串
Label6.Text = BitConverter.ToString(base64byte);
发表评论
-
定制 attribute
2013-02-15 13:13 1069现在让我们来 ... -
委 托
2012-12-31 16:30 1395回调函数是一种非常有 ... -
数 组
2012-05-23 11:49 874所有数组类型都隐式地从System.Array抽象类派生,后者 ... -
枚举类型和位标识
2012-05-16 12:52 1239枚举类型定义了一组 “符号/值” 配对 namespace ... -
接 口
2012-02-20 21:03 968CLR不支持多继承(因而所有托管编程语言也不支持)。CLR只是 ... -
泛 型
2012-02-12 15:39 1133面向对象的编程方式有一种好处是“代码重用”,泛型是CLR和编程 ... -
事 件
2011-12-25 17:54 838现在让我们来讨论类型中可定义的最后一种成员:事件 类型之所以 ... -
属性
2011-11-20 15:34 790属性允许源代码用一个 ... -
参 数
2011-10-22 15:30 744以引用的方式向方法传递参数 默认情况下,CLR假定所有方法都 ... -
方法
2011-10-07 15:09 887实例构造器和类(引用类型) 构造器(constructor) ... -
常量和字段
2011-10-06 15:30 950定义常量符号时,它的值必须能在编译时确定。确定之后 ... -
类型和成员基础
2011-09-17 22:16 790常量通常与类型关联,而不与类型的实例关联。从逻辑上讲,常量始终 ... -
基元类型、引用类型和值类型
2011-08-26 22:46 1186编译器直接支持的数据类型称为基元类型。基元类型直接映射到Fra ... -
CLR类型基础
2011-08-15 00:11 2606people p=new people() 以上面例子 ... -
CLR的执行模型
2011-08-01 14:57 835CLR(Common Language Runtime)公共语 ...
相关推荐
常用的文本处理方法,比如过滤关键词。文本编码。去除 htmlCode 中所有的HTML标签(包括标签中的属性)。截取字符串。将Gb2312编码的字符串转换为utf-8。判断是否有非法字符。分割字符串。检测含中文字符串实际长度。...
"文本重复字符串查找"是其中一个重要的子任务,它的目的是找出文本中出现多次的相同字符串。这个工具显然允许用户进行定制化的搜索,比如设置重复字符串的最小长度以及排除某些特定的字符串。这种功能对于识别文本中...
RF(Regular Expression,正则表达式)是一种强大的文本处理工具,广泛应用于字符串截取、比较和切割等任务。在这个"rf.rar"压缩包中,我们看到涉及到RF字符串处理的三个关键知识点:RF字符串截取、RF字符串比较以及...
字符串处理函数是编程语言中非常重要的工具,它们用于操作、分析和操纵文本数据。以下是一些常见的字符串处理函数,这些函数通常在C语言或其他类似语言中使用,虽然这里没有提供具体的编程语言环境,但理解这些函数...
本软件主要用于对字符串文本中的多余空格、回车、换行、制表符等进行处理,软件能自动识别中英文,分别采用不同的处理方式。开发目的:在阅读文献资料时需要复制其中部分文本,而这些文本中通常包括有多余的格式,...
HTML字符串与富文本之间的转换在iOS开发中是一个常见的需求,特别是在处理从服务器获取的数据时,这些数据可能包含HTML标签,需要在本地应用中正确显示。本文将深入探讨这个主题,并结合给定的"NSAttributedString4...
这个"纯C++ 字符串处理函数大全源码"正是为了满足这种需求而设计的,它包含了作者自定义封装的一系列字符串操作函数。 首先,`StringProcess.cpp`和`StringProcess.h`是C++中的源代码文件和头文件。`.cpp`文件通常...
VB提供了一系列的内置函数来帮助程序员进行字符串的操作和处理,使得对字符串的管理和分析变得更加方便。本资料主要汇总了VB中的常用字符串处理函数,适用于初学者学习和参考。 1. **Left()** 函数:返回字符串的...
编写程序从某个文本文件中读入若干个字符串(文本文件中每行一个字符串,每个字符串长度不超过80个字符),将字符串按字典序(从小到大)排序,结果输出到另一个文本文件中。要求此程序能处理任意多个字符串。
在易语言编程环境中,倒转字符串是一个常见的操作,可以用于各种文本处理任务。本文将详细介绍八种不同的方法来实现这一功能,并提供相应的源码。易语言作为一款中文编程语言,以其简洁直观的语法深受初学者和专业...
VBA 提供了多种字符串处理函数,包括比较字符串、转换字符串、创建字符串、获取字符串的长度、格式化字符串、查找字符串、提取字符/字符串、删除空格、返回字符代码、返回数值代表的相应字符、使用字节的函数、返回...
汇编语言中的字符串处理虽然相对复杂,但掌握了其核心原理和操作流程,就能高效地完成各种字符串相关的任务。通过灵活运用寄存器和控制指令,可以实现从简单搜索到复杂文本分析的各种功能,为软件开发提供强大的底层...
无论是进行数据解析、日志分析,还是构建复杂的文本处理算法,有效的字符串操作都能极大地提高代码的效率和可读性。因此,花时间学习和实践这些基本技能是每个程序员职业生涯中不可或缺的一部分。
C#中文文本匹配,字符串匹配,中文词语匹配,计算2个句子相似度 中文匹配C#中文文本匹配,字符串匹配,中文词语匹配,计算2个句子相似度 C#中文文本匹配,字符串匹配,中文词语匹配,计算多个句子相似度 C#中文文本...
在Python编程语言中,字符和字符串是处理文本数据的基础元素。字符串是一种标准的数据类型,它由一个或多个字符组成,可以包含字母、数字、标点符号、空格、特殊符号等。在Python中,字符串可以用单引号或双引号来...
"统计字符串中子字符串出现的次数,并返回"是一个常见的需求,广泛应用于文本分析、数据挖掘以及日志处理等多个场景。本篇文章将深入探讨如何在C#中实现这一功能,以及涉及到的相关知识点。 首先,我们要明确字符串...
只需确保字符串本身和分隔符都是正确的Unicode编码,LabVIEW就能正确识别和处理中文字符。 五、实例演示 假设我们有一个包含中文的字符串“我喜欢 LabVIEW,它很强大”。可以使用“字符串到数组”函数,将这个字符...
2. 检查和处理空格:如果无用信息指的是空格,可以使用`字符串删除`函数,传入`字符串_原`和“空格”作为参数,删除所有空格。 3. 处理特殊字符:若要移除特殊字符,你需要列出这些字符,然后遍历字符串,使用`字符...
本资源“ios-富文本处理字符串.zip”显然是关于如何在iOS应用中实现这种功能的示例代码或教程。 首先,我们来看“指定字符串中特定字符串字体颜色和大小”这一知识点。在iOS中,我们可以使用NSAttributedString和...