C#快速入門教程(20)—— 字串與正規表示式
前面,我們已經瞭解了string型別的字串,它是System.String型別的別名,定義為不可變字串型別,也就是說,當一個字串的內容確定以後就不能再修改了,如果對字串內容進行操作就會重新分配記憶體來儲存新的字串物件,這樣以來,對於字串的處理效率就不會太高。本課,我們將討論幾個關於字串處理的主題,主要包括String類、StringBuilder類、字串格式化、正規表示式,以及如何使用擴充套件方法來封裝程式碼等。
String類
我們知道,C#中的string型別實際上就是System.String類的別名,這樣就可以使用String類的成員來操作字串了,下面,我們瞭解String類中屬性和方法的基本應用。
首先,我們使用Length屬性可以獲取字串中的字元數量,使用Split()方法可以分割字串,下面的程式碼演示了這兩個成員的使用。
static void Main(string[] args)
{
string s = "abc,def,ghi";
Console.WriteLine("字元數:{0}",s.Length);
string[] arr = s.Split(',');
for (int i = 0; i < arr.Length; i++)
{
Console.WriteLine(arr[i]);
}
}
程式碼執行結果如下圖所示。
請注意Split()方法的引數,這裡使用了一個逗號(char型別)作為分割字元,而在實際應用中還可以使用更多的分割方法,可以參考MSDN文件靈活應用;String類中的基本成員的應用同樣可以參考MSDN文件。
StringBuilder類
StringBuilder類定義在System.Text名稱空間,用於對文字內容進行高效的操作,如組合、修改、替換等操作。
對文字內容進行組合操作時,StringBuilder物件就比String物件高效;如下面的程式碼,我們將多個字串內容進行組合,基中使用了Append()和AppendFormat()方法,它們可以將多種型別的資料新增到物件中,並組合為文字內容。
using System;
using System.Text;
namespace ConsoleTest
{
class Program
{
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
sb.Append("abc");
sb.AppendFormat(",{0},{1}","def","ghi");
Console.WriteLine(sb.ToString());
}
}
}
本例中,我們使用了StringBuilder類的無引數建構函式,實際上,還有一些比較常用的建構函式版本可以使用,如:
- StringBuilder(int),引數用於指定StringBuilder物件初始尺寸(可儲存的字元數),有利於合理分配記憶體空間。
- StringBuilder(string,int),引數一用於指定初始值,引數二用於指定物件的初始尺寸。
由於StringBuider物件在建立時已經分配了初始尺寸,所以,在對其內容操作的效率就會比String物件高;在連線多個字串,或者是將其他型別資料組合成字串時,使用Append()和AppendFormat()方法是非常方便的,如下面的程式碼,我們將int型別的資料新增到StringBuilder物件中。
StringBuilder sb = new StringBuilder("abc",32);
sb.AppendFormat("中有{0}個字元",sb.Length);
Console.WriteLine(sb.ToString());
下面,再來了解StringBuilder類中幾個常用的方法。
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder("def",128);
sb.Insert(0, "abc,");
Console.WriteLine(sb.ToString());
sb.Replace("def", "xyz");
Console.WriteLine(sb.ToString());
}
本例,我們使用了StringBuilder物件的兩個方法,分別是:
- Insert()方法,用於在物件指定的位置插入新內容,引數一指定插入的位置,使用從0到始的索引值;引數二指定插入的內容,可以是各種型別的資料。
- Replace()方法,將原文字內容中,引數一指定的內容變為引數二指定的內容。
這兩個方法都有一些過載版本,大家可以引數MSDN文件使用。實際開發中,還可以參考StringBuilder物件的更多成員進行操作,從而更高效地處理文字的操作。
字串格式化
前面,我們使用過的Console.WriteLine()方法、StringBuilder物件中的AppendFormat()方法,都可以使用引數進行文字的組合操作,實際上,string.Format()方法也可以完成同樣的任務,只是它們的使用場景不一樣,接下來,我們以string.Format()方法為例來討論格式化輸入字串的問題。
String.Format()方法的第一個引數是一個字串,其中可以使用{0}、{1}等標識指定資料的引數的順序,即{0}為方法的第二個引數,{1}為方法的第三個引數,以此類推;這裡,除了使用資料索引,還可以使用一個字母指定資料的格式,如:
- C字元,顯示為貨幣格式(當前系統設定)。
- D字元,顯示整數,並指定顯示的位數。
- E字元,顯示科學計數法格式。
- F字元,顯示為浮點數格式,並可指定小數的位數。
- N字元,使用數字分隔。
- P字元,顯示百分比格式。
- X字元,顯示為十六進位制格式;使用x時,a至f顯示為小寫形式。
在這些格式化字串中,除了X的大小寫輸出有區別,其他的字元是不區分大小寫,下面的程式碼演示了字串格式輸出的一些操作。
static void Main(string[] args)
{
Console.WriteLine("{0:C}",1.23);
Console.WriteLine("{0:D2}",123);
Console.WriteLine("{0:D5}", 123);
Console.WriteLine("{0:F2}",1);
Console.WriteLine("{0:F2}", 1.225);
Console.WriteLine("{0:N}",123456789.0123);
Console.WriteLine("{0:P2}",0.1);
Console.WriteLine("{0:P2}",0.125);
Console.WriteLine("{0:X}", 15);
Console.WriteLine("{0:x}", 15);
}
程式碼執行結果如下圖所示。
正規表示式
簡單的說,正規表示式是通過模式(pattern)來匹配(match)文字內容,並可以進一步操作,如判斷文字格式、查詢和替換內容等。正規表示式的相關資源定義在System.Text.RegularExpressions名稱空間,請注意在程式碼中引用。
使用正規表示式時,模式的定義是很關鍵的,也是難度比較大的操作,我們先通過一個示例來了解正規表示式的基本操作方法;下面的程式碼,我們判斷一個字串的內容是否為6位數字(如郵政編碼或縣級行政區劃程式碼)。
using System;
using System.Text.RegularExpressions;
namespace ConsoleTest
{
class Program
{
static void Main(string[] args)
{
string p = "[0-9]{6}?";
Console.WriteLine(Regex.IsMatch("123456",p));
Console.WriteLine(Regex.IsMatch("12345",p));
Console.WriteLine(Regex.IsMatch("abcdef", p));
}
}
}
程式碼輸出結果如下圖所示。
本例中,首先使用”[0-9]{6}?”定義了一個模式,其中有兩個部分,第一部分指定了匹配的內容,[0-9]表示0到9數字中一個;第二部分指定內容出現的規則,{6}?表示前面的內容剛好出現6次。實際應用中,匹配內容中還可以使用轉義字元(可以參考字串相關課程);如果不指定出現規則,則內容預設匹配一次。
下面給出一些常用的內容匹配方式。
- [],匹配其中的一個字元,如[yn]匹配y或n、[a-z]匹配字母a到z、[0-9]匹配0到9的數字。
- [^],不包含^後指定的字元。
- .字元,匹配換行符(\n)以外的所有字元。
- \w,匹配大小寫字母、數字和下畫線。
- \W,匹配大小寫字母、數字和下畫線以外的字元。
- \s,匹配空白字元,如空格、製表符等。
- \S,匹配空白字元以外的字元(可見字元)。
- \d,匹配十進位制數字。
- \D,匹配十進位制數字以外的字元。
下面是一些常用的應用規則。
- ^,指定匹配的內容在字串的開始部分。
- $,指定匹配內容在字串的結尾部分,或換行符(\n)前。
- *,匹配前一內容0次或多次。
- +,匹配前一內容1次或多次。
- ?,匹配前一內容0次或1次。
- {n},匹配前一內容n次。
- {n,},匹配前一內容最少n次。
- {n,m},匹配前一內容在n到m次之間。
- {n}?,匹配前一內容正好n次。
- {n,}?,匹配前一內容至少n次,但儘可能少。
- {n,m}?,匹配前一內容n到m次,但儘可能多。
正規表示式的功能是非常強大的,合理地應用正規表示式也可以讓大量的文字操作事半功倍,但熟練掌握則需要大量的思考、實踐和總結;下面,我們會封裝幾個關於字串操作的方法,其中就包括正規表示式的應用。
使用擴充套件方法封裝程式碼
首先,我們定義一個靜態類CStr,其中定義一個Combine()方法,如下面的程式碼。
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleTest
{
public static class CStr
{
// 組合文字內容
public static string Combine(this string s,params object[] args)
{
return string.Format(s, args);
}
//
}
}
這個程式碼看起來並不複雜,只是對string.Format()方法進行了封裝,下面,我們再看如何使用這個方法。
namespace ConsoleTest
{
class Program
{
static void Main(string[] args)
{
string s = "{0},{1}".Combine("abc", 123);
Console.WriteLine(s);
}
}
}
只要引用了CStr類所在的名稱空間,我們就可以直接在string物件中使用Combine()方法,為什麼呢?實際上,我們在定義CStr.Combine()方法時需要注意幾個地方,一是CStr類定義為靜態的,這樣,它的成員也都應該定義為靜態的;而Combine()方法的第一個引數使用了this關鍵字和string型別,這就會將Combine()方法定義為string型別的擴充套件方法。
使用擴充套件方法可以更方便的封裝專案中所需要的常用程式碼,使用起來也更加方便,如按順序連線字串和不同型別資料的操作就可以封裝為CStr.Append()方法,如下面的程式碼。
// 連線字串和基本資料型別
public static string Append(this string s, params object[] objs)
{
StringBuilder sb = new StringBuilder(s, 128);
for (int i = 0; i < objs.Length; i++)
sb.Append(objs[i]);
return sb.ToString();
}
下面,我們再封裝兩個關於正規表示式的應用。
// 判斷是否為電子郵件地址
public static bool IsEmail(this string addr)
{
string p = @"^[a-zA-Z0-9](\w+\.)*\w+@(\w+\.)+\w+$";
return Regex.IsMatch(addr, p);
}
// 判斷是否是11位手機號
public static bool IsMobile(this string num)
{
string p = @"1[0-9]{10}?";
return Regex.IsMatch(num, p);
}
下面的程式碼演示了CStr類中Append()方法、IsEmail()方法和IsMobile()方法的使用。
static void Main(string[] args)
{
Console.WriteLine("abc".Append(",def",123,"***"));
Console.WriteLine("xxx@yyy.zzz".IsEmail());
Console.WriteLine("123@163.com".IsEmail());
Console.WriteLine("abc.xyz".IsEmail());
Console.WriteLine("12345678910".IsMobile());
Console.WriteLine("123456789".IsMobile());
Console.WriteLine("21345678910".IsMobile());
Console.WriteLine("a2345678910".IsMobile());
}
程式碼執行結果如下圖所示。
請注意,手機號碼和電子郵件只能判斷其格式,如果需要在專案中判斷其有效性,只能通過實際聯絡來驗證,比如常用的方法——給使用者郵箱發個驗證郵件。
本課,我們討論了關於字串和正規表示式常用的操作資源,大家可以在學習和實踐中不斷積累自己的程式碼庫,並進行合理的封裝,以便在專案中靈活、快速地實現所需要的功能。
CHY軟體小屋原創作品!
相關文章
- C++與正規表示式入門C++
- C#快速入門教程(17)—— 委託、事件與Lambda表示式C#事件
- Regex 正規表示式入門
- JS正規表示式入門JS
- 【記錄】正規表示式入門
- 正規表示式入門學習
- 字串——正規表示式匹配字串
- JS正規表示式從入門到入土(10)—— 字串物件方法JS字串物件
- 正規表示式 教程
- 正規表示式從入門到入坑
- 【正規表示式】常用的正規表示式(數字,漢字,字串,金額等的正規表示式)字串
- 20個Python 正規表示式應用與技巧Python
- 瞎說系列之正規表示式入門
- 正規表示式系列之初級入門篇
- 瞭解下C# 正規表示式C#
- 20個實用正規表示式
- 【深入淺出ES6】字串與正規表示式字串
- Swift 正規表示式完整教程Swift
- 正規表示式簡明教程
- C#快速入門教程(11)—— 字元和字串型別C#字元字串型別
- C# 正規表示式提取字串中括號裡的值C#字串
- 正規表示式中 “$” 並不是表示 “字串結束字串
- 《MySQL 入門教程》第 20 篇 通用表表示式MySql
- 如何快速學習正規表示式
- 正規表示式的字串替換方法字串
- 學習正規表示式(js、C#)JSC#
- 深入理解ES6--2.字串與正規表示式字串
- lambda表示式——快速入門
- 正規表示式完整教程(略長)
- (一) 爬蟲教程 |正規表示式爬蟲
- 深入理解正規表示式:從入門到精通
- 快速掌握grep命令及正規表示式
- 正規表示式刪除字串兩端空格字串
- 演算法之字串——正規表示式匹配演算法字串
- 正規表示式提取指定字元之間字串字元字串
- C#快速入門教程(25)—— 日期與時間C#
- JS正規表示式從入門到入土(5)—— 量詞JS
- 正規表示式