C#字符串和正则表达式

来源:互联网 发布:mysql语句书写顺序 编辑:程序博客网 时间:2024/04/30 09:20

0.string类

简单字符串操作用string类,对应IL中的System.String类,有很多足够常用的字符串操作,但是频繁操作效率非常低下,所以其它方式的字符串操作同样必不可缺。每次生成一个新的实例都要申请新的堆资源,和回收旧的资源

1.StringBuilder

频繁更改:频繁创建字符串和多次创建较长的字符串,那么需要用System.TextStringBuilder类提高性能。可以指定最大Capacity,当前长度是Length,当没有指定最大长度时候,那么会翻倍递增内存。但是只提供了Replace,Append/AppendFormat,Remove的字符串操作。StringBuilder不能转换为String(隐式和显式都不行),唯一转换为String的方法是ToString函数。简单的字符串用string即可。

StringBuilder实例代码:

static void Main() {   // StringBuilder实际用的长度是Length,当前容量是Capacity超过了会加倍,   // 只读属性MaxCapacity是最大容易超过了会报错。   // StringBuilder(150, 1000)150是Capacity后面的1000是MaxCapacity            StringBuilder greetingBuilder =               new StringBuilder("Hello from all the guys at Wrox Press. ", 150);            greetingBuilder.Append("We do hope you enjoy this book as much as we enjoyed writing it");            for(int i = (int)'z'; i>=(int)'a' ; i--)            {               char old1 = (char)i;               char new1 = (char)(i+1);               greetingBuilder = greetingBuilder.Replace(old1, new1);            }            for(int i = (int)'Z'; i>=(int)'A' ; i--)            {               char old1 = (char)i;               char new1 = (char)(i+1);               greetingBuilder = greetingBuilder.Replace(old1, new1);            }            Console.WriteLine("Encoded:\n" + greetingBuilder);            Console.ReadLine();  }

2.IFormattable接口的ToString函数

格式化:格式化字符串使用两个有效的接口,称为IFormatProvider和IFormattable来处理。
Console.WriteLine就是调用了String.Format方法来格式化的,String.Format构造格式化的字符串调用了StringBuilder构造函数和StringBuilder的AppendFormat方法,AppendFormat方法会首先检查对象实现了IFormattable接口就调用ToString(string format, IFormatProvider formatProvider),测试失败会调用对象Object.ToString()。

所以自定义类和结构,重写了Object.ToString就可以在Console.WriteLine中输出。所有的基元类型都实现了IFormattable接口。
如果要自定义的类和结构,不调用Object.ToString方法格式化,那么需要实现IFormattable接口的string ToString(string format, IFormatProvider formatProvider)方法
例如:

class MainEntryPoint   {      static void Main()      {         Vector v1 = new Vector(1,32,5);         Vector v2 = new Vector(845.4, 54.3, -7.8); // 传入:IJK,:VE,:N格式化说明字符         Console.WriteLine("\nIn IJK format,\nv1 is {0,30:IJK}\nv2 is {1,30:IJK}", v1, v2);         Console.WriteLine("\nIn default format,\nv1 is {0,30}\nv2 is {1,30}", v1, v2);         Console.WriteLine("\nIn VE format\nv1 is {0,30:VE}\nv2 is {1,30:VE}", v1, v2);         Console.WriteLine("\nNorms are:\nv1 is {0,20:N}\nv2 is {1,20:N}", v1, v2);  Console.ReadLine();      }   }   // 需要继承System.IFormattable接口   struct Vector : IFormattable   {      public double x, y, z;      public Vector(double x, double y, double z)      {         this.x = x;         this.y = y;         this.z = z;      }    // 重写System.IFormattable的string ToString(string format, IFormatProvider formatProvider)函数// IFormatProvider formatProvider类型系统默认根据当前文化背景提供,不需要处理。      public string ToString(string format, IFormatProvider formatProvider)      {         if (format == null)            return ToString();         string formatUpper = format.ToUpper();         switch (formatUpper)         {            case "N":               return "|| " + Norm() + " ||";            case "VE":               return String.Format("( {0:E}, {1:E}, {2:E} )", x, y, z);            case "IJK":               StringBuilder sb = new StringBuilder(x.ToString(), 30);               sb.Append(" i + ");               sb.Append(y.ToString());               sb.Append(" j + ");               sb.Append(z.ToString());               sb.Append(" k");               return sb.ToString();            default:               return ToString();          }      }

3.RegularExpressions

正则表达式:对于字符串复杂的查找,替换,提取某个类型的或者具体的字符串,那么可以用正则表达式来处理,在System.Text.RegularExpressions命名空间中。
正则表达式中的字符串查找替换提取删除操作,都可以使用String和StringBuilder来做到,但是有时候字符串操作比较复杂,需要大量的这些基本字符串的操作,如果用正则表达式,则可以用很少的代码解决。
正则表达式经典应用:
1)字符串模式验证,例如是否是邮箱模式,是否是有效的身份证。
2)多个元组直接存储需要的信息,或用或形式,提取出多个需要要的信息。
3)字符串的一些指定的替换。


js中的正则表达式:
RegExp对象由字符模式和搜索范围组成。
字符串模式的类型:
(1). 字符和模式,连续出现组合关系:字符串长度确定的模式(包括确定的字符串和模糊匹配的字符)"%d%d/%d%d/%d%d%d%d", “Jackson”,本身就是表达了与的关系。
(2).自定义逻辑组合/或/非:字符串模式中任意一个都遍历目标串的模式([], (),逻辑与或|, ^非),[AEIOUaeiou]匹配元音,“([a-z][A-Z][0-9])+”()是将几个或组合在一起匹配aB0。”[to|too|2]”;^在[]内为非,否则为定位符号;与可以用或来表达/[^\w\s]/g。
(3). 数量:字符模式个数的修饰,+,-,*,?,{n}元符号;“fo+”与football匹配,+为至少有一个或者多个这样的字符。
(4). 位置:字符串模式位置的修饰,^,$,\b, \B;”ar$”和car匹配。
(5). 转义符号\, “Th\*”与Th*匹配,常规模式在字符串中也要”\\s”,前面的\也是转义字符。


搜索范围有i, g, m:
i 执行对大小写不敏感的匹配。
g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
m 执行多行匹配。

C#中使用正则表达式模式和js一致,要用模式中的\符号,那么需要将输入转换到字符串时候保持,所以需要"\\"或者@"\"。
C#中的正则表达式需要用到RegularExpressions命名空间,Regex对象, MatchCollection字符匹配后枚举结果,Match单个匹配字符串封装。
正则表达式使用实例:

using System;using System.Text.RegularExpressions;namespace Wrox.ProCSharp.RegularExpressionPlayaround{   class MainEntryPoint   {      static void Main()      {         Find3();         Console.ReadLine();      }      static void Find1()      {         const string text = @"XML has made a major impact in almost every aspect of             software development. Designed as an open, extensible, self-describing             language, it has become the standard for data and document delivery on             the web. The panoply of XML-related technologies continues to develop             at breakneck speed, to enable validation, navigation, transformation,             linking, querying, description, and messaging of data.";         const string pattern = @"\bn\S*ion\b"; // matches正则表达式运算返回的结果         MatchCollection matches = Regex.Matches(text, pattern,             RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture);// 输出结果         WriteMatches(text, matches);      }      static void Find2()      {         const string text = @"XML has made a major impact in almost every aspect of             software development. Designed as an open, extensible, self-describing             language, it has become the standard for data and document delivery on             the web. The panoply of XML-related technologies continues to develop             at breakneck speed, to enable validation, navigation, transformation,             linking, querying, description, and messaging of data.";         const string pattern = @"\bn";         MatchCollection matches = Regex.Matches(text, pattern,             RegexOptions.IgnoreCase);         WriteMatches(text, matches);      }    static void Find3()  {    // 1)从文本中提取出指定的模式  Console.WriteLine("从文本中提取出指定的模式");  const string urlText = "sljflsfj sfjlsjf fj http://blog.csdn.net/blues1021";  const string pattern = @"\b(\S+)://([^:]+)(?::(\S+))?\b";  MatchCollection matches = Regex.Matches(urlText, pattern,             RegexOptions.IgnoreCase);  WriteMatches(urlText, matches);// 2)截取需要的字符串信息 类似C原因中的sscanf     // string url = "http://www.contoso.com:8080/letters/readme.html"; // const string pattern2 = @"^(?<proto>\w+)://[^/]+?(?<port>:\d+)?/"; Console.WriteLine("截取需要的字符串信息 类似C原因中的sscanf"); const string textCapture = "http://blog.csdn.net/blues1021"; const string patternCapture = @"^(?<proto>\w+)://?(?<address>[^/]+)/?(?<name>\S+)";         Regex r = new Regex(patternCapture,RegexOptions.None, TimeSpan.FromMilliseconds(150));         Match m = r.Match(textCapture);         if(m.Success) { string strProtocal = m.Result("${proto}"); string strAddress = m.Result("${address}");   string strName = m.Result("${name}");  Console.WriteLine("Parse Protocal: " + strProtocal + ", Address:" + strAddress + ", Name:" + strName ); // Console.WriteLine(m.Result("${proto}:${port}"));  }  }      static void WriteMatches(string text, MatchCollection matches)      {         Console.WriteLine("Original text was: \n\n" + text + "\n");         Console.WriteLine("No. of matches: " + matches.Count);         foreach (Match nextMatch in matches)         {// nextMatch是当前匹配的字符的委托对象,Match.Index属性            int index = nextMatch.Index;// Match.ToString功能            string result = nextMatch.ToString();// 匹配在字符串中间,字符前面取5个字符索引长度,否则取当前字符索引长度,charsBefore是相对位置            int charsBefore = (index < 5) ? index : 5;// 剩下的字符长度            int fromEnd = text.Length - index - result.Length;// 剩下的字符长度太小了就是剩下字符长度,否则取5个长度            int charsAfter = (fromEnd < 5) ? fromEnd : 5;// 需要展示的字符长度位置,目的是为了说明该查找提取出来的字符所在原来字符串中的位置。            int charsToDisplay = charsBefore + charsAfter + result.Length;            Console.WriteLine("Index: {0}, \tString: {1}, \t{2}",               index, result,    // 截取附近的字符串               text.Substring(index - charsBefore, charsToDisplay));         }      }   }}
了解更多的复杂字符串的正则表达式操作,.net也提供了相应的类GroupCollection,CaptureColleciton等。

0 0