本章节将讲述关于字符串方面的处理问题。
7.1 创建字符串
如果多次修改一个字符串的话,处理效率会变得效率低下。对于这种情况下,应该使用C#专门处理较长字符串的一个类:system.text.bulider,该类是专门用来处理上述问题的。
下面给出使用代码:
stringbuilderDemo
using System;
using System.Collections.Generic;
using System.Text;
namespace Wrox.ProCSharp.StringEncoder
{
class MainEntryPoint
{
static void Main(string[] args)
{
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 Old = (char)i;
char New = (char)(i+1);
greetingBuilder = greetingBuilder.Replace(Old, New);
}
for(int i = (int)'Z'; i>=(int)'A' ; i--)
{
char Old = (char)i;
char New = (char)(i+1);
greetingBuilder = greetingBuilder.Replace(Old, New);
}
Console.WriteLine("Encoded:\n" + greetingBuilder.ToString());
}
}
}
using System.Collections.Generic;
using System.Text;
namespace Wrox.ProCSharp.StringEncoder
{
class MainEntryPoint
{
static void Main(string[] args)
{
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 Old = (char)i;
char New = (char)(i+1);
greetingBuilder = greetingBuilder.Replace(Old, New);
}
for(int i = (int)'Z'; i>=(int)'A' ; i--)
{
char Old = (char)i;
char New = (char)(i+1);
greetingBuilder = greetingBuilder.Replace(Old, New);
}
Console.WriteLine("Encoded:\n" + greetingBuilder.ToString());
}
}
}
说明:使用该类并不是总能提高性能的,只有基于处理多个字符串时使用。但如果只是处理连接连个字符串的话,最好还是使用string类比较好。
7.2 格式化字符串
格式化字符串就是能够以各种方法显示变量的内容,.net运行库中定义了一种标准方法:使用接口IFormatetable。
下面给出字符串格式表
字符 | 说明 | 示例 | 输出 |
---|---|---|---|
C 或 c | 货币 | Console.Write("{0:C}", 2.5);
Console.Write("{0:C}", -2.5); |
$2.50
($2.50) |
D 或 d | 十进制 | Console.Write("{0:D5}", 25); | 00025 |
E 或 e | 科学型 | Console.Write("{0:E}", 250000); | 2.500000E+005 |
F 或 f | 固定点 | Console.Write("{0:F2}", 25);
Console.Write("{0:F0}", 25); |
25.00
25 |
G 或 g | 常规 | Console.Write("{0:G}", 2.5); | 2.5 |
N 或 n | 数字 | Console.Write("{0:N}", 2500000); | 2,500,000.00 |
X 或 x | 十六进制 | Console.Write("{0:X}", 250);
Console.Write("{0:X}", 0xffff); |
FA
FFFF |
interface IFormattable
{
string ToString(string formate,IFormateProvider formateProvider);
}
接着来实现字符串格式化:
实现字符串重载
using System;
using System.Collections.Generic;
using System.Text;
namespace Wrox.ProCSharp.FormattableVector
{
class MainEntryPoint
{
static void Main()
{
Vector v1 = new Vector(1, 32, 5);
Vector v2 = new Vector(845.4, 54.3, -7.8);
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);
}
}
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;
}
public string ToString(string format, IFormatProvider formatProvider)
{
if (format == null)
return ToString();
string formatUpper = format.ToUpper();
switch (formatUpper)
{
case "N":
return "|| " + Norm().ToString() + " ||";
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();
}
}
public Vector(Vector rhs)
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
}
public override string ToString()
{
return "( " + x + " , " + y + " , " + z + " )";
}
public double this[uint i]
{
get
{
switch (i)
{
case 0:
return x;
case 1:
return y;
case 2:
return z;
default:
throw new IndexOutOfRangeException(
"Attempt to retrieve Vector element" + i);
}
}
set
{
switch (i)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
case 2:
z = value;
break;
default:
throw new IndexOutOfRangeException(
"Attempt to set Vector element" + i);
}
}
}
/* public static bool operator == (Vector lhs, Vector rhs)
{
if (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z)
return true;
else
return false;
}*/
private const double Epsilon = 0.0000001;
//以下都是重载运算
public static bool operator ==(Vector lhs, Vector rhs)
{
if (System.Math.Abs(lhs.x - rhs.x) < Epsilon &&
System.Math.Abs(lhs.y - rhs.y) < Epsilon &&
System.Math.Abs(lhs.z - rhs.z) < Epsilon)
return true;
else
return false;
}
public static bool operator !=(Vector lhs, Vector rhs)
{
return !(lhs == rhs);
}
public static Vector operator +(Vector lhs, Vector rhs)
{
Vector Result = new Vector(lhs);
Result.x += rhs.x;
Result.y += rhs.y;
Result.z += rhs.z;
return Result;
}
public static Vector operator *(double lhs, Vector rhs)
{
return new Vector(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);
}
public static Vector operator *(Vector lhs, double rhs)
{
return rhs * lhs;
}
public static double operator *(Vector lhs, Vector rhs)
{
return lhs.x * rhs.x + lhs.y + rhs.y + lhs.z * rhs.z;
}
public double Norm()
{
return x * x + y * y + z * z;
}
}
}
using System.Collections.Generic;
using System.Text;
namespace Wrox.ProCSharp.FormattableVector
{
class MainEntryPoint
{
static void Main()
{
Vector v1 = new Vector(1, 32, 5);
Vector v2 = new Vector(845.4, 54.3, -7.8);
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);
}
}
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;
}
public string ToString(string format, IFormatProvider formatProvider)
{
if (format == null)
return ToString();
string formatUpper = format.ToUpper();
switch (formatUpper)
{
case "N":
return "|| " + Norm().ToString() + " ||";
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();
}
}
public Vector(Vector rhs)
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
}
public override string ToString()
{
return "( " + x + " , " + y + " , " + z + " )";
}
public double this[uint i]
{
get
{
switch (i)
{
case 0:
return x;
case 1:
return y;
case 2:
return z;
default:
throw new IndexOutOfRangeException(
"Attempt to retrieve Vector element" + i);
}
}
set
{
switch (i)
{
case 0:
x = value;
break;
case 1:
y = value;
break;
case 2:
z = value;
break;
default:
throw new IndexOutOfRangeException(
"Attempt to set Vector element" + i);
}
}
}
/* public static bool operator == (Vector lhs, Vector rhs)
{
if (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z)
return true;
else
return false;
}*/
private const double Epsilon = 0.0000001;
//以下都是重载运算
public static bool operator ==(Vector lhs, Vector rhs)
{
if (System.Math.Abs(lhs.x - rhs.x) < Epsilon &&
System.Math.Abs(lhs.y - rhs.y) < Epsilon &&
System.Math.Abs(lhs.z - rhs.z) < Epsilon)
return true;
else
return false;
}
public static bool operator !=(Vector lhs, Vector rhs)
{
return !(lhs == rhs);
}
public static Vector operator +(Vector lhs, Vector rhs)
{
Vector Result = new Vector(lhs);
Result.x += rhs.x;
Result.y += rhs.y;
Result.z += rhs.z;
return Result;
}
public static Vector operator *(double lhs, Vector rhs)
{
return new Vector(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);
}
public static Vector operator *(Vector lhs, double rhs)
{
return rhs * lhs;
}
public static double operator *(Vector lhs, Vector rhs)
{
return lhs.x * rhs.x + lhs.y + rhs.y + lhs.z * rhs.z;
}
public double Norm()
{
return x * x + y * y + z * z;
}
}
}
7.3 正则表达式
正则表达式主要是用来处理字符串的语言,这个在js上面用的很多。
下面给出简单使用示例:
正则表达式demo
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace Wrox.ProCSharp.RegularExpressionPlayaround
{
class MainEntryPoint
{
static void Main()
{
Find1();
Console.ReadLine();
}
static void Find1()
{
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.";
string pattern = @"\bn\S*ion\b";
MatchCollection matches = Regex.Matches(text, pattern,
RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace |
RegexOptions.ExplicitCapture);
WriteMatches(text, matches);
}
static void Find2()
{
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.";
string pattern = @"\bn";
MatchCollection matches = Regex.Matches(text, pattern,
RegexOptions.IgnoreCase);
WriteMatches(text, matches);
}
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)
{
int Index = nextMatch.Index;
string result = nextMatch.ToString();
int charsBefore = (Index < 5) ? Index : 5;
int fromEnd = text.Length - Index - result.Length;
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));
}
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace Wrox.ProCSharp.RegularExpressionPlayaround
{
class MainEntryPoint
{
static void Main()
{
Find1();
Console.ReadLine();
}
static void Find1()
{
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.";
string pattern = @"\bn\S*ion\b";
MatchCollection matches = Regex.Matches(text, pattern,
RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace |
RegexOptions.ExplicitCapture);
WriteMatches(text, matches);
}
static void Find2()
{
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.";
string pattern = @"\bn";
MatchCollection matches = Regex.Matches(text, pattern,
RegexOptions.IgnoreCase);
WriteMatches(text, matches);
}
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)
{
int Index = nextMatch.Index;
string result = nextMatch.ToString();
int charsBefore = (Index < 5) ? Index : 5;
int fromEnd = text.Length - Index - result.Length;
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));
}
}
}
}
小结:这一章节写的比较少,主要讲了如何字符串各种方法。下一章节将讲泛型