一、字符串
在C#中,字符串是一系列不可修改的Unicode字符,創建字符串后,就不能修改它。要創建字符串,最常用的方法是聲明一個 string 變量,并將一串用引號括起的字符(字符串字面值)賦給它,如下所示。
string myString = “Hello World~”;
ps:字符串暫留
如果在同一個程序集中有兩個相同的字符串字面值,那么運行環境將只為該字面值的所有實例創建一個 string 對象。這被稱為字符串暫留(string interning),C#編譯器使用這種方式來消除重復的字符串字面值,以節省內存空間并減少執行字符串比較所需的時間。
使用相等運算符對字符串字面值進行比較時,字符串暫留可能有時導致意外的結果:
object obj = "String";
string string1 = "String";
string string2 = typeof(string).Name;
Console.WriteLine(string1 == string2); //true
Console.WriteLine(obj == string1); //true
Console.WriteLine(obj == string2); //false
第一項比較檢查值是否相當,這意味著它檢查兩個字符串的內容是否相同。第二和第三項比較檢查引用是否相等,因為比較的是object和string。如果在程序中輸入上述代碼,就將出現兩條警告消息:“可能非有意的引用比較;若要獲取值比較,請將左邊轉換為‘string’”。
字符串暫留只適用于字符串字面值,因此 string2 的值不會被暫留,因為它不是字面值。這意味著obj和string2指向內存中的不同對象,因此該引用比較的結果為false。
字符串字面值可包含特殊的轉義序列,用于表示不可打印的字符,如制表符和換行符。轉義序列以反斜桿(\)打頭。如果要在字符串字面值中包含反斜桿,也必須對其進行轉義。
下表列出了C#定義的字符轉義序列
轉義序列 | 描述 |
---|---|
' | 單引號,用于字符字面值 |
" | 雙引號,用于字符串字面值 |
|反斜杠 | |
\0 | Unicode字符0 |
\a | 警報(char 7) |
\b | Backspace(char 8) |
\f | 換頁(char 12) |
\n | 換行(char 10) |
\r | 回車(char 13) |
\t | 水平制表符(char 9) |
\v | 垂直制表符(char 11) |
\uxxxx | 對應十六進制值xxxx的字符的Unicode轉義序列:還有包含1~4個數字之的變長版本 |
\uxxxxxxxx | 對應十六進制值xxxxxxxx的字符的Unicode轉義序列,用于生成Unicode代理區字符(srrogates) |
創建字符串字面值時,另一種方法是使用原義字符串(verbatim string literal),這種字符串以@和雙引號打頭。使用原義字符串的好處是,編譯器按原樣處理字符串,即使字符串跨越多行或包含轉義字符。在原義字符串中,只有雙引號需要轉義—使用兩個雙引號表示,以便編譯器知道字符串的終止位置。
編譯器遇到原義字符串時,將它轉換為合適的轉義字符串。如下演示了4個字符串,其中前兩個等價,雖然原義字符串更容易閱讀。后兩個字符串也等價,其中multipleLine2是轉換后的字符串字面值。
string stringLiteral = "\\Microsoft Visual Studio Code\\VC#";
string verbatimLiteral = @"\Microsoft Visual Studio Code\VC#";
string multipleLines = @"This is a ""line"" of text. And this is the second line.";
string multipleLines2 = "This is a \"line\" of text.\nAnd this is the second line.";
ps:ToString方法
還可調用ToString方法來創建字符串。由于這個方法是在System.Object中聲明的,因此每個對象都有它,但其默認實現為返回類名。所有預定義的類型都重寫了ToString,以提供有意義的字符串表示。
1.1 空字符串
未賦值的字符串變量為 null,空字符串與此不同,它是在雙引號之間沒有任何字符的字符串(“”)。
ps:使用String.Empty還是”"
String.Empty 和“”之間沒有差別,使用哪一個取決于個人喜好,但String.Empty通常更容易理解。
要判斷字符串是否為空,最快捷、最簡單的方法是檢查其Length屬性是否為零。然而,由于字符串屬于引用類型,因此字符串變量的值可能為 null,如果試圖訪問這種字符串變量的Length屬性,就將導致運行階段錯誤。鑒于經常需要判斷字符串是否為空,C#提供了靜態方法String.IsNullOrEmpty,如下所示
public static bool IsNullOrEmpty(string value)
{
if (value != null)
{
return (value.Length == 0);
}
return true;
}
另外,還經常需要判斷字符串是否只包含空格,為此可使用靜態方法String.IsNullOrWhite Space,如下所示
public static bool IsNullOrEmpty(string value)
{
if (value != null)
{
for (int i=0; i < value.Lenth;i++)
{
if (!char.IsWhiteSpace(value[i]))
{
return false;
}
}
}
return true;
}
使用方法String.IsNullOrEmpty和String.IsNullOrWhiteSpace有助于確保代碼正確、易讀和一致,因此每當需要判斷字符串是否為null、為空或只包含空格字符時,都應使用它們。
1.2 字符串操作
System.String 類提供了大量的方法和屬性,可用于操作字符串。實際上,System.String定義了40多個公有成員。
雖然字符串屬于基本數據類型,且通常將字符串數據作為一個整體進行操作,但是字符串畢竟是由字符組成的。要判斷字符串包含多少個字符,可使用Length屬性。不同于其他語言(如C和C++)中的字符串,C#字符串沒有包含終止字符。由于字符串是由字符組成的,因此可通過位置訪問其中的各個字符,就像字符串是字符數組一樣。
提取子串
子串是字符串的一部分,System.String提供了多個方法可用于查找和提取子串。
為提取子串,String提供了一個重載的Substring方法,讓你能夠指定起始字符位置,還可指定要提取的子串長度。如果沒有指定長度,就將從指定的起始位置提取到字符串末尾。
第一個子串從字符位置10開始,到字符串末尾結束,結果為 brown fox;第二個子串為 quick。
string original = "The quick brown fox";
string substring = original.Substring(10);
string substring2 = original.Substring(4, 5);
以這種方法提取子串很靈活,尤其是結合使用其他方法找出字符在字符串中的位置時。
方法IndexOf和LastIndexOf分別指出指定的字符或字符串首次和最后一次出現的位置。如果要確定一組給定字符中的任何一個首次或最后一次出現的位置,就可以使用方法 IndexOfAny和LastIndexOfAny。如果找到匹配的字符或字符串,就將返回該字符或字符串的起始位置的索引(更直觀的說法是偏移量),否則將返回-1。如果搜索的字符串或字符為空,就將返回0。
比較字符串
要對字符串進行比較,以判斷一個字符串是否等于或包含另一個字符串,可使用方法Compare、CompareOrdinal、CompareTo、Contains、Equals、EndsWith和StartsWith。
靜態方法Copmare有10個重載版本,讓您能夠控制比較的很多方面,如區分大小寫、區域敏感、從什么地方開始比較以及最多比較多少個字符。
ps:字符串比較規則
默認情況下,使用任何Compare方法時,都以區分大小寫和區域敏感的方式進行比較。使用相等運算符==時,總是按序號排序規則(ordinal)進行比較。
如果要根據數字序列值對字符串進行比較,可使用重載的靜態方法CompareOrdinal(總共有兩個版本)。調用該方法時,可指定從兩個字符串的什么地方開始比較以及最多比較多少個字符。
方法CompareTo將當前字符串與指定的字符串進行比較,并返回一個整數值,它指出當前字符串在排序順序中位于指定字符串之前、之后還是同一個位置。
方法Contains使用序號排序規則(ordinal sorting rules)進行搜索,能夠判斷當前字符串是否包含指定字符串。如果找到了指定字符串或指定字符串為空,那么該方法將返回true。
方法StartsWith和EndsWith(它們總共有6個重載版本)能夠判斷當前字符串的開頭或結尾是否與指定字符串匹配。就像Compare方法一樣,也可指定比較時是否區分大小寫以及要使用的區域規則。
ps:改變大小寫
雖然字符串比較方法讓您能夠執行區分大小寫的比較,但是也可將字符串轉換為全部大寫或全部小寫。這不斷有助于比較字符串,還有助于將字符串數據的表示標準化。
要改變大小寫,標準方式是使用方法ToUpperInvariant,它使用固定區域性的大小寫規則將字符串轉換為全部大寫。要將字符串轉換為全部小寫,最好使用方法ToLowerInvariant,它使用固定區域性的大小寫規則。除帶invariant的方法外,還可使用方法ToUpper和ToLower,它們使用當前區域或指定區域的大小寫規則,這取決于您使用的是哪個重載版本。
修改字符串的某些部分
除經常需要比較字符串外,有時候還需要修改字符串。由于字符串是不可變的,因此這些方法實際上返回一個新字符串,而不是修改當前字符串。
要刪除字符串中的空格和其他字符,可使用方法Trim、TrimEnd 或TrimStart。TrimEnd和TrimStart分別刪除當前字符串開頭或末尾的空格,而Trim將兩端的空格都刪除。
要將字符串擴展(填充)到特定的長度,可使用方法PadLeft或PadRight。默認情況下,這些方法使用空格填充,但是它們都有重載版本,讓您能夠指定要使用的填充字符。
String 類還提供了一組重載的方法,讓您能夠通過刪除或替換現有字符串中的字符來創建新的字符串。方法Remove從字符串的指定位置開始刪除,直到到達字符串末尾或刪除了指定數量的字符。方法 Replace 將指定的字符或字符串都替換為另一個字符或字符串,它執行序號搜索,即區分大小寫,但是不區分區域性。
字符串拼接、串聯和拆分
前面介紹了多種使用字符串字面值和子串創建新字符串的方法,還可通過合并現有字符串來創建新字符串,稱之為字符串拼接(concatenation)。
ps:使用加法運算符拼接字符串
加法運算符實際上調用方法Concat的合適重載版本。
通常以兩種方式拼接字符串。最常見的方式是使用重載的加法運算符(+)拼接多個字符串;也可使用方法Concat的9個重載版本之一,它讓您能夠拼接任意數量的字符串。如下代碼演示了這兩種拼接方法。
string string1 = "this is " + " basic concatenation.";
string string2 = String.Concat("this", "is", "more", "advanced","concatenation");
與拼接緊密相關的一種概念是串聯(join)字符串,這種概念使用方法Join。不同于方法Concat,方法Join將一組指定的字符串拼接起來,同時在字符串之間加上指定的分隔符。
如果說串聯是合并一組字符串,那么相反的操作就是根據分隔字符將字符串拆分成數量不確定的子串,這是使用方法Split完成的,這個方法接受一組字符或字符串并將其視為分隔符。
如下代碼將一系列字符串串聯起來,然后基于相同的分隔符將字符串拆分。首先,創建了一個包含10個字符串的數組,并使用分隔符#將這些字符串串聯起來。然后,基于分隔符#將得到的字符串進行拆分,并將所有單詞顯示出來—每個單詞占一行。
string[] strings = new string[10];
for (int i = 0; i <10;i++)
{
string[i] = String.Format("{0}",i * 2);
}
string joined = String.Join("#",strings);
Console.WriteLine(joined);
foreach (string word int joined.Splite(new char[] { '#' }))
{
Console.WriteLine(word);
}
二、使用StringBuilder創建可變的字符串
由于字符串是不可變的,因此每當執行字符串操作時,都將創建新的臨時字符串。為創建可變字符串,以免操作它時無需創建新字符串,C#提供了StringBuilder類。如果要拼接的字符串數量是固定的,那么使用 string 更合適;如果要拼接的字符串數量不確定(如迭代語句中),那么使用StringBuilder更合適。
StringBuilder 支持在當前字符串末尾附接數據、在指定位置插入數據、替換數據以及從當前字符串刪除數據。要附接數據,可使用方法Append或AppendFormat的重載版本之一。
方法Append將對象的文本或字符串表示加在當前字符串末尾;方法AppendFormat支持使用復合格式化(composite formatting)在當前字符串末尾追加文本。由于方法AppendFormat使用復合格式化,因此可以向它傳遞一個格式字符串
如下所示使用StringBuilder字符串串聯和分拆
StringBuilder stringBuilder = new StringBuilder();
for(int i=0;i<10;i++)
{
stringBuilder.AppendFormat("{0}#",i*2);
} //Remove the trailing '#' character.
stringBuilder.Remove(stringBuilder.Length - 1,1);
string joined = String.Join("#",stringBuilder.ToString());
Console.WriteLine(joined);
foreach(string word int joined.Split(new char[] { '#' }))
{
Console.WriteLine(word);
}
要插入數據,可使用方法 Insert 的重載版本之一。插入數據時,必須指定要在當前StringBuilder的什么位置插入。要刪除數據,可使用Remove方法,并指出從什么位置開始刪除以及要刪除多少個字符。要將當前StringBuilder中的字符替換為另一個字符,可使用方法Replace的重載版本之一。方法Replace還支持對當前StringBuilder的子串中的字符進行替換,其中子串是使用起始位置和長度指定的。
ps:StringBuilder的容量
在幕后,StringBuilder存儲在緩沖區中,以便能夠支持拼接。僅當緩沖區沒有足夠的空間容納新數據時,才需要給StringBuilder分配額外的內存。
內部緩沖區的默認大小(容量)為16個字符。當緩沖區已滿時,將分配額外的緩沖區空間,以容納更多的字符,新分配的緩沖區空間大小由容量指定。StringBuilder還有最大容量,其值為Int32.Maxvalue,即231個字符。
當前字符串的長度可使用屬性Length設置。如果設置的Length值比當前容量大,容量將自動改變。同樣,通過將 Length 設置成比當前容量小,將截斷當前字符串。
三、類型格式化
通過設置格式,可將類實例、結構或枚舉值轉換為字符串表示。從System.Object派生而來的每種類型都自動繼承了一個沒有參數的ToString方法,這個方法默認返回類型的名稱。所有預定義的值類型都重寫了ToString方法,使其返回值的字符串表示。
ToString 返回類型的名稱通常沒有意義,您可重寫 ToString 方法,使其返回值的字符串表示
如下的Contact類重寫了ToString方法
class Contact
{
private string firstName;
private string lastName;
public override string ToString()
{
return firstName + " " + lastName;
}
}
ps:重寫ToString方法
給自己創建的類重寫ToString方法前,務必知道這樣一點:通過調試器查看對象時,Visual Studio調試工具大量使用ToString來確定將該對象顯示為什么樣的值。
對象的值通常有多種表示,ToString 允許通過參數傳遞一個格式字符串,以指定字符串表示是什么樣的。格式字符串包含一個或多個格式說明符,它們定義了字符串表示應該是什么樣的。
3.1 標準格式字符串
標準格式字符串包含一個格式說明符和一個可選的精度說明符,其中格式說明符是單個字符,而精度說明符影響結果中顯示的位數。精度說明符可以是0~99的任何整數。所有數值類型、日期和時間類型以及枚舉類型都支持一組預定義的標準格式字符串,其中包括標準格式說明符G,它表示值的常規字符串表示。
標準格式說明符:
格式說明符 | 描述 |
---|---|
G、g | 常規字符串表示 對于所有的數值類型,結果為最緊湊的定點表示法或科學計數法。精度說明符制定了有效位數 對于所有日期和時間類型,表示常規日期/時間模式。G表示長時間模式,而g表示短時間模式 對于枚舉類型,在可能的情況下顯示字符串值,否則顯示整數值。如果定義枚舉時制定了特性Flags,將每個有效枚舉的字符串值拼接起來,并用逗號分隔;如果沒有指定Flags特性,就將無效枚舉值顯示為整數 |
X、x | 對于整數類型,結果為十六進制表示。精度說明符制定了位數。 對于枚舉值,顯示為十六進制表示。必要時添加前導零,以確保長度最少8位 |
D、d | 對于整數類型,結果為十進制表示和可選的符號。精度說明符制定了最少位數 對于枚舉類型,顯示為最短的整數值 |
E、e | 只有數值類型支持它,結果為科學計數法表示。精度說明符制定了小數位數,默認為6位。 |
F、f | 對于所有的數值類型,結果為整數部分、小數部分和可選的符號。精度說明福指定了小數位數 對于日期和時間類型,表示完整日期/時間模式。F表示長時間模式,而f表示短時間模式 對于枚舉類型,盡可能顯示為字符串值。如果值為一系列有效枚舉值之和,就將其表示為這些有效枚舉值對應的字符串的拼接,并用逗號將字符串分隔(即使沒有指定Flags特性也如此);否則,顯示為整數值 |
N、n | 只有數值類型支持。結果為整數部分、小數部分、千位分隔符、小數點和可選的負號。精度說明符制定了小數位數 |
P、p | 只有數值類型支持。結果為原數值的100倍和百分符號。精度說明符制定了小數位數 |
R、r | 對于Single、Double和BigInteger,結果為原數值的字符串表示,并忽略精度說明符 對于日期和時間類型,表示RFC1123模式 |
M、m | 只有日期和時間類型支持,表示月/日模式 |
O、o | 只有日期和時間類型支持,表示返回日期/時間模式 |
s | 只有日期和時間類型支持,表示可排序日期/時間模式 |
t | 只有日期和時間類型支持,表示短時間模式 |
T | 只有日期和時間類型支持,表示長時間模式 |
u | 只有日期和時間類型支持,表示通用可排序日期/時間模式 |
U | 只有日期和時間類型支持,表示通用完整日期/時間模式 |
Y、y | 只有日期和時間類型支持,表示年/月模式 |
使用標準格式字符串設置了一個Days枚舉值的格式:
Days days = Days.Monday;
string[] formats = {"G", "F", "D", "X"};
foreach (string format indexer formats)
{
Console.WriteLine(days.ToString(format));
}
對于自己創建的類,除重寫方法ToString外,還可定義標準格式說明符,方法是定義一個ToString(string)方法。類應支持下列功能:
格式說明符G表示常規格式。重寫不接受任何參數的方法ToString時,應讓它調用ToString(string),并傳遞標準格式字符串G。
如果格式字符串為null,就應將其視為相當于指定了格式說明符G。
如下使用ToString支持標準格式字符串
struct float Degress;public Celsius(float temperature)
{
this.Degrees = temperature;
}
public string ToString()
{
return this.ToString("C");
}
public string ToString(string format)
{
if (String.IsNullOrWhiteSpace(format))
{
format = "C";
}
format = format.ToUpperInvariant().Trim();
switch(format)
{
case "C":
case "c":
return this.Degrees.ToString("N2") +" "C";
case "F":
case "f":
return (this.Degrees *9 / 5 + 32).ToString("N2") +" "F";
case "K":
case "k":
return (this.Degrees +273.15f).TosString("N2") +""K";
default:
throw new FormatExcpetion();
}
}
3.2 自定義格式字符串
自定義格式字符串由一個或多個自定義格式說明符組成,定義了值的字符串表示。如果格式字符串只包含一個自定義格式說明符,就應在它前面加上百分符號(%),以免與標準格式說明符混淆。
所有數值類型以及日期和時間類型都支持自定義格式字符串,而很多標準日期和時間格式字符串還是自定義格式字符串的別名。使用自定義格式字符串時,可通過組合多個自定義格式說明符來定義格式,這提供了極大的靈活性。
自定義格式說明符:
格式說明符 | 描述 |
---|---|
0 | 只有數值類型支持。如果有相應的數字,就使用數字替換0;否則,在結果中保留0 |
# | 只有數值類型支持。如果有相應的數字,就使用數字替換#;否則,不出現在結果中 |
. | 只有數值類型支持,指定小數點在結果中的未知 |
, | 只有數值類型支持。作為千位分隔符時,在千位組之間插入本地化千位分隔符:作為數字比例換算說明符時,每指定一個逗號,就將數字除以1000。要用作數字比例換算說明符,必須緊鄰顯示或隱式小數點左側 |
% | 只有數值類型支持。將數字乘以100,并插入一個本地化百分符號 |
‰ | 只有數值類型支持。將數字乘以1000,并插入一個本地化千分符號。‰相當于Unicode符號U+2030 |
E0、E + 0、E - 0、 e0、e + 0、e - 0 |
只有數值類型支持。如果后面至少跟一個零,就使用指數表示法顯示結果。E和e表示使用大寫還是小寫的指數符號,而后跟多少個零表示指數至少有多少位。加號(+)表示指數前面總是有符號,而減號(-)表示僅當指數為負時才在指數前面加上符號 |
; | 只有數值類型支持。用于分隔多個部分,這些部分分別制定正數、負數和零的格式。如果只包含一部分(默認設置),那么這部分將用于設置所有制的格式;如果有兩部分,那么第一部分用于設置正值和零的格式,第二部分用于設置負值的格式;如果包括三部分,那么第一部分用于設置正值的格式,第二部分用于設置負值的格式,第三部分用于設置零的格式 |
d | 只有日期和時間類型支持,顯示一月的哪天,用1~31表示 |
dd | 只有日期和時間類型支持,顯示一月的哪天,用01~31表示 |
ddd | 只有日期和時間類型支持,顯示星期幾的縮寫 |
dddd | 只有日期和時間類型支持,顯示星期幾的完整名稱 |
g、gg | 只有日期和時間類型支持,顯示紀元 |
h | 只有日期和時間類型支持,顯示采用12小時制的小時,用0~11表示 |
hh | 只有日期和時間類型支持,顯示采用12小時制的小時,用00~11表示 |
H | 只有日期和時間類型支持,顯示采用24小時制的小時,用0~23表示 |
HH | 只有日期和時間類型支持,顯示采用24小時制的小時,用00~23表示 |
K | 只有日期和時間類型支持,顯示時區信息 |
m | 只有日期和時間類型支持,顯示用0~59表示的分鐘 |
mm | 只有日期和時間類型支持,顯示用00~59表示的分鐘 |
M | 只有日期和時間類型支持,顯示用1~12表示的月份 |
MM | 只有日期和時間類型支持,顯示月份,用01~12表示 |
MMM | 只有日期和時間類型支持,顯示月份的縮寫 |
MMMM | 只有日期和時間類型支持,顯示月份的完整名稱 |
s | 只有日期和時間類型支持,顯示用0~59表示的秒 |
ss | 只有日期和時間類型支持,顯示用00~59表示的秒 |
t | 只有日期和時間類型支持,顯示AM/PM指示符的第一個字符 |
tt | 只有日期和時間類型支持,顯示AM/PM指示符 |
y | 只有日期和時間類型支持,顯示用0~99表示的年份 |
yy | 只有日期和時間類型支持,顯示用00~99表示的年份 |
yyy | 只有日期和時間類型支持,顯示至少用3位數表示的年份 |
yyyy | 只有日期和時間類型支持,顯示用4位數表示的年份 |
yyyyy | 只有日期和時間類型支持,顯示用5位數表示的年份 |
z | 只有日期和時間類型支持,顯示與UTC相差多少小時,沒有前導零 |
zz | 只有日期和時間類型支持,顯示與UTC相差多少小時,對于個位數,將加上前導零 |
zzz | 只有日期和時間類型支持,顯示與UTC相差多少小時、多少分鐘 |
: | 只有日期和時間類型支持,顯示時間分隔符 |
/ | 只有日期和時間類型支持,顯示日期分隔符 |
'字符串'、"字符串" | 字符串字面值分隔符。將引號內的字符按原樣復制到結果中 |
轉義字符,導致將下一個字符視為字符字面值,而不是自定義格式說明符 | |
其他 | 其他字符都按原樣復制到結果中 |
3.3 復合格式化
使用復合格式化的方法接受一個復合格式字符串和一個對象列表作為參數。復合格式字符串定義了一個模板,它由固定文本和帶索引的占位符組成,其中帶索引的占位符稱為格式項,對應于列表中的對象。使用復合格式化時,指定的格式項不能多于列表中的對象,但是列表中的對象可比格式項多。
格式項的語法:
{index[,alignment][:formatString]}
ps:index和大括號是必不可少的
索引對應于參數列表中對象的位置。索引從零開始,但是多個格式項可使用相同的索引,而格式項可以任何順序排列,并可指向列表中的任何對象。
alignment 部分是可選的,它指定了首選的字段寬度。如果為正值,字段就將右對齊;如果為負值,字段就將左對齊。如果指定的值比格式化后的字符串長度小,就將忽略alignment值。
formatString部分使用標準格式字符串或自定義格式字符串。如果沒有指定,就將使用常規格式說明符G。
舉個栗子
Celsius temp = new Celsius(28);
//Using composite formatting width String.Format.
string resault = String.Format("On {0:d}, the high temperature was {1}.", DateTime.Today,temp);
Console.WriteLine(result);
//Using composite formatting width Console.WriteLine.
Console.WriteLine ("On {0:d}, the high temperature was {1}.", DateTime.Today,temp);
四、正則表達式
正則表達式常被稱為模式,描述了一組字符串。可將正則表達式應用于字符串,以確定該字符串是否與指定的模式匹配、返回一個或一系列子串、返回對原始字符串修改后得到的新字符串。
ps:正則表達式的兼容性
.NET Framework中的正則表達式與Perl 5正則表達式兼容,包含其他正則表達式實現(如Perl和awk)中最受歡迎的功能,還新增了其他實現中沒有的功能。
正則表達式本身就是一種編程語言,用于操作文本并針對文本操作進行了優化,這是使用字面字符和元字符(metacharacter)實現的。字面字符指的是目標字符串必須與之匹配的字符,而元字符正則表達式分析器如何行動。表達式分析器負責解釋正則表達式并將其應用于目標字符串。這些元字符賦予了正則表達式靈活性和強大的處理功能。
如下表是常用正則表達式的元字符
元字符 | 描述 |
---|---|
. | 與任何一個字符匹配,但換行符(\n)除外 |
[] | 與包含在方括號內的任何一個字符匹配,還可使用字符“-”指定匹配的字符范圍 |
[^] | 與任何一個不包含在方括號內的字符匹配 |
^ | 指定從行首開始匹配 |
$ | 指定匹配的內容應位于行尾 |
\w | 匹配一個單詞字符,與[a-zA-z_0-9]等價 |
\W | 匹配非單詞字符 |
\s | 匹配空白字符,相當于[\n\r\t\f] |
\S | 匹配非空白字符 |
\d | 匹配一個十進制數字,相當于[0-9] |
\D | 匹配非十進制數字 |
* | 匹配零或多個它前面的元素 |
+ | 匹配一個或多個它前面的元素 |
? | 匹配零或一個它前面的元素 |
{n} | 匹配/n個它前面的元素 |
{n,} | 匹配/n個或更多個它前面的元素 |
{n,m} | 匹配/n-m/個它前面的元素 |
丨 | 匹配用豎線分隔的表達式之一 |
() | 定義一個未命名捕獲組 |
(?<name>) (?'name') |
定義一個命名捕獲組 |
(?<number>) (?'number') |
定義一個編號捕獲組 |
4.1 C#中的正則表達式
在.NET Framework中,正則表達式是通過命名空間 System.Text.RegularExpression中的幾個類實現的,這些類讓您能夠分析和應用正則表達式以及使用捕獲組。
4.1.1 Regex類
Regex類提供了正則表達式分析器和引擎的實現,它將正則表達式應用于輸入字符串。通過使用這個類,可以快速分析大量文本,看其是否符合特定模式,還可輕松地提取和編輯子串。
Regex 類提供了實例成員和靜態成員,讓您能夠以兩種不同的方式使用它。當您創建Regex 類的實例時,不會編譯和緩存表達式模式;但是當您使用靜態方法時,將編譯和緩存表達式模式。默認情況下,正則表達式引擎將緩存最近使用的15個靜態正則表達式。如果需要大量使用一組固定的正則表達式,就應使用靜態方法,而不是相應的實例方法。
4.1.2 Match和MatchCollection類
使用Regex類的Match方法將正則表達式應用于字符串時,將用Match類的實例表示第一個匹配項。MatchCollection包含一組Match實例,這些Match是通過重復應用正則表達式找到的匹配項。
4.1.3 Group和Capture類
Match.Groups屬性表示單個匹配項中所有的捕獲組。每個捕獲組都是一個Group實例,而Group實例包含一組Capture對象,這些對象可通過Captures屬性獲取。Capture表示單個子表達式匹配返回的結果。
4.2 使用正則表達式驗證字符串
正則表達式的一種常見用途是驗證字符串:檢查它是否符合特定模式。為此,可使用方法IsMatch的重載版本之一。
4.3 使用正則表達式搜索子串
正則表達式還可用于搜索與特定正則表達式模式匹配的子串。這種搜索可執行一次,也可重復執行。在前一種情況下,將返回第一個匹配項;在后一種情況下,將返回一系列匹配項。
要以這種方式搜索子串,可使用方法Match或Matches。其中,前者返回第一個匹配項,而后者返回一系列不重疊的匹配項。