# C# 正則表達式
**正則表達式** 是一種匹配輸入文本的模式。.Net 框架提供了允許這種匹配的正則表達式引擎。模式由一個或多個字符、運算符和結構組成。
## 定義正則表達式
下面列出了用于定義正則表達式的各種類別的字符、運算符和結構。
* 字符轉義
* 字符類
* 定位點
* 分組構造
* 限定符
* 反向引用構造
* 備用構造
* 替換
* 雜項構造
### 字符轉義
正則表達式中的反斜杠字符(\)指示其后跟的字符是特殊字符,或應按原義解釋該字符。
下表列出了轉義字符:
| 轉義字符 | 描述 | 模式 | 匹配 |
| --- | --- | --- | --- |
| **\a** | 與報警 (bell) 符 \u0007 匹配。 | \a | "Warning!" + '\u0007' 中的 "\u0007" |
| **\b** | 在字符類中,與退格鍵 \u0008 匹配。 | [\b]{3,} | "\b\b\b\b" 中的 "\b\b\b\b" |
| **\t** | 與制表符 \u0009 匹配。 | (\w+)\t | "Name\tAddr\t" 中的 "Name\t" 和 "Addr\t" |
| **\r** | 與回車符 \u000D 匹配。(\r 與換行符 \n 不是等效的。) | \r\n(\w+) | "\r\Hello\nWorld." 中的 "\r\nHello" |
| **\v** | 與垂直制表符 \u000B 匹配。 | [\v]{2,} | "\v\v\v" 中的 "\v\v\v" |
| **\f** | 與換頁符 \u000C 匹配。 | [\f]{2,} | "\f\f\f" 中的 "\f\f\f" |
| **\n** | 與換行符 \u000A 匹配。 | \r\n(\w+) | "\r\Hello\nWorld." 中的 "\r\nHello" |
| **\e** | 與轉義符 \u001B 匹配。 | \e | "\x001B" 中的 "\x001B" |
| **\ nnn** | 使用八進制表示形式指定一個字符(nnn 由二到三位數字組成)。 | \w\040\w | "a bc d" 中的 "a b" 和 "c d" |
| **\x nn** | 使用十六進制表示形式指定字符(nn 恰好由兩位數字組成)。 | \w\x20\w | "a bc d" 中的 "a b" 和 "c d" |
| **\c X \c x** | 匹配 X 或 x 指定的 ASCII 控件字符,其中 X 或 x 是控件字符的字母。 | \cC | "\x0003" 中的 "\x0003" (Ctrl-C) |
| **\u nnnn** | 使用十六進制表示形式匹配一個 Unicode 字符(由 nnnn 表示的四位數)。 | \w\u0020\w | "a bc d" 中的 "a b" 和 "c d" |
| **\** | 在后面帶有不識別的轉義字符時,與該字符匹配。 | \d+[\+-x\*]\d+\d+[\+-x\*\d+ | "(2+2) * 3*9" 中的 "2+2" 和 "3*9" |
### 字符類
字符類與一組字符中的任何一個字符匹配。 下表列出了字符類:
| 字符類 | 描述 | 模式 | 匹配 |
| --- | --- | --- | --- |
| **[character_group]** | 匹配 character_group 中的任何單個字符。 默認情況下,匹配區分大小寫。 | [mn] | "mat" 中的 "m","moon" 中的 "m" 和 "n" |
| **[^character_group]** | 非:與不在 character_group 中的任何單個字符匹配。 默認情況下,character_group 中的字符區分大小寫。 | [^aei] | "avail" 中的 "v" 和 "l" |
| **[ first - last ]** | 字符范圍:與從 first 到 last 的范圍中的任何單個字符匹配。 | (\w+)\t | "Name\tAddr\t" 中的 "Name\t" 和 "Addr\t" |
| **.** | 通配符:與除 \n 之外的任何單個字符匹配。 若要匹配原意句點字符(. 或 \u002E),您必須在該字符前面加上轉義符 (\.)。 | a.e | "have" 中的 "ave", "mate" 中的 "ate" |
| **\p{ name }** | 與 _name_ 指定的 Unicode 通用類別或命名塊中的任何單個字符匹配。 | \p{Lu} | "City Lights" 中的 "C" 和 "L" |
| **\P{ name }** | 與不在 _name_ 指定的 Unicode 通用類別或命名塊中的任何單個字符匹配。 | \P{Lu} | "City" 中的 "i"、 "t" 和 "y" |
| **\w** | 與任何單詞字符匹配。 | \w | "Room#1" 中的 "R"、 "o"、 "m" 和 "1" |
| **\W** | 與任何非單詞字符匹配。 | \W | "Room#1" 中的 "#" |
| **\s** | 與任何空白字符匹配。 | \w\s | "ID A1.3" 中的 "D " |
| **\S** | 與任何非空白字符匹配。 | \s\S | "int __ctr" 中的 " _" |
| **\d** | 與任何十進制數字匹配。 | \d | "4 = IV" 中的 "4" |
| **\D** | 匹配不是十進制數的任意字符。 | \D | "4 = IV" 中的 " "、 "="、 " "、 "I" 和 "V" |
### 定位點
定位點或原子零寬度斷言會使匹配成功或失敗,具體取決于字符串中的當前位置,但它們不會使引擎在字符串中前進或使用字符。 下表列出了定位點:
| 斷言 | 描述 | 模式 | 匹配 |
| --- | --- | --- | --- |
| **^** | 匹配必須從字符串或一行的開頭開始。 | ^\d{3} | "567-777-" 中的 "567" |
| **$** | 匹配必須出現在字符串的末尾或出現在行或字符串末尾的 **\n** 之前。 | -\d{4}$ | "8-12-2012" 中的 "-2012" |
| **\A** | 匹配必須出現在字符串的開頭。 | \A\w{3} | "Code-007-" 中的 "Code" |
| **\Z** | 匹配必須出現在字符串的末尾或出現在字符串末尾的 **\n** 之前。 | -\d{3}\Z | "Bond-901-007" 中的 "-007" |
| **\z** | 匹配必須出現在字符串的末尾。 | -\d{3}\z | "-901-333" 中的 "-333" |
| **\G** | 匹配必須出現在上一個匹配結束的地方。 | \\G\(\d\) | "(1)(3)(5)[7](9)" 中的 "(1)"、 "(3)" 和 "(5)" |
| **\b** | 匹配必須出現在 **\w**(字母數字)和 **\W**(非字母數字)字符之間的邊界上。 | \w | "Room#1" 中的 "R"、 "o"、 "m" 和 "1" |
| **\B** | 匹配不得出現在 **\b** 邊界上。 | \Bend\w*\b | "end sends endure lender" 中的 "ends" 和 "ender" |
### 分組構造
分組構造描述了正則表達式的子表達式,通常用于捕獲輸入字符串的子字符串。 下表列出了分組構造:
| 分組構造 | 描述 | 模式 | 匹配 |
| --- | --- | --- | --- |
| **( subexpression )** | 捕獲匹配的子表達式并將其分配到一個從零開始的序號中。 | (\w)\1 | "deep" 中的 "ee" |
| **(?< name >subexpression)** | 將匹配的子表達式捕獲到一個命名組中。 | (?< double>\w)\k< double> | "deep" 中的 "ee" |
| **(?< name1 -name2 >subexpression)** | 定義平衡組定義。 | (((?'Open'\()[^\(\)]*)+((?'Close-Open'\))[^\(\)]*)+)*(?(Open)(?!))$ | "3+2^((1-3)*(3-1))" 中的 "((1-3)*(3-1))" |
| **(?: subexpression)** | 定義非捕獲組。 | Write(?:Line)? | "Console.WriteLine()" 中的 "WriteLine" |
| **(?imnsx-imnsx:subexpression)** | 應用或禁用 _subexpression_ 中指定的選項。 | A\d{2}(?i:\w+)\b | "A12xl A12XL a12xl" 中的 "A12xl" 和 "A12XL" |
| **(?= subexpression)** | 零寬度正預測先行斷言。 | \w+(?=\.) | "He is. The dog ran. The sun is out." 中的 "is"、 "ran" 和 "out" |
| **(?! subexpression)** | 零寬度負預測先行斷言。 | \b(?!un)\w+\b | "unsure sure unity used" 中的 "sure" 和 "used" |
| **(?< =subexpression)** | 零寬度正回顧后發斷言。 | (?< =19)\d{2}\b | "1851 1999 1950 1905 2003" 中的 "51" 和 "03" |
| **(?< ! subexpression)** | 零寬度負回顧后發斷言。 | (?< !19)\d{2}\b | "end sends endure lender" 中的 "ends" 和 "ender" |
| **(?> subexpression)** | 非回溯(也稱為"貪婪")子表達式。 | \[13579\](?>A+B+) | "1ABB 3ABBC 5AB 5AC" 中的 "1ABB"、 "3ABB" 和 "5AB" |
### 限定符
限定符指定在輸入字符串中必須存在上一個元素(可以是字符、組或字符類)的多少個實例才能出現匹配項。 限定符包括下表中列出的語言元素。 下表列出了限定符:
| 限定符 | 描述 | 模式 | 匹配 |
| --- | --- | --- | --- |
| **\*** | 匹配上一個元素零次或多次。 | \d*\.\d | ".0"、 "19.9"、 "219.9" |
| **+** | 匹配上一個元素一次或多次。 | "be+" | "been" 中的 "bee", "bent" 中的 "be" |
| **?** | 匹配上一個元素零次或一次。 | "rai?n" | "ran"、 "rain" |
| **{ n }** | 匹配上一個元素恰好 n 次。 | ",\d{3}" | "1,043.6" 中的 ",043", "9,876,543,210" 中的 ",876"、 ",543" 和 ",210" |
| **{ n ,}** | 匹配上一個元素至少 n 次。 | "\d{2,}" | "166"、 "29"、 "1930" |
| **{ n , m }** | 匹配上一個元素至少 n 次,但不多于 m 次。 | "\d{3,5}" | "166", "17668", "193024" 中的 "19302" |
| **\*?** | 匹配上一個元素零次或多次,但次數盡可能少。 | \d*?\.\d | ".0"、 "19.9"、 "219.9" |
| **+?** | 匹配上一個元素一次或多次,但次數盡可能少。 | "be+?" | "been" 中的 "be", "bent" 中的 "be" |
| **??** | 匹配上一個元素零次或一次,但次數盡可能少。 | "rai??n" | "ran"、 "rain" |
| **{ n }?** | 匹配前導元素恰好 n 次。 | ",\d{3}?" | "1,043.6" 中的 ",043", "9,876,543,210" 中的 ",876"、 ",543" 和 ",210" |
| **{ n ,}?** | 匹配上一個元素至少 n 次,但次數盡可能少。 | "\d{2,}?" | "166"、 "29" 和 "1930" |
| **{ n , m }?** | 匹配上一個元素的次數介于 n 和 m 之間,但次數盡可能少。 | "\d{3,5}?" | "166", "17668", "193024" 中的 "193" 和 "024" |
### 反向引用構造
反向引用允許在同一正則表達式中隨后標識以前匹配的子表達式。 下表列出了反向引用構造:
| 反向引用構造 | 描述 | 模式 | 匹配 |
| --- | --- | --- | --- |
| **\ number** | 反向引用。 匹配編號子表達式的值。 | (\w)\1 | "seek" 中的 "ee" |
| **\k< name >** | 命名反向引用。 匹配命名表達式的值。 | (?< char>\w)\k< char> | "seek" 中的 "ee" |
### 備用構造
備用構造用于修改正則表達式以啟用 either/or 匹配。 下表列出了備用構造:
| 備用構造 | 描述 | 模式 | 匹配 |
| --- | --- | --- | --- |
| **|** | 匹配以豎線 (|) 字符分隔的任何一個元素。 | th(e|is|at) | "this is the day. " 中的 "the" 和 "this" |
| **(?( expression )yes | no )** | 如果正則表達式模式由 expression 匹配指定,則匹配 _yes_;否則匹配可選的 _no_ 部分。 expression 被解釋為零寬度斷言。 | (?(A)A\d{2}\b|\b\d{3}\b) | "A10 C103 910" 中的 "A10" 和 "910" |
| **(?( name )yes | no )** | 如果 name 或已命名或已編號的捕獲組具有匹配,則匹配 _yes_;否則匹配可選的 _no_。 | (?< quoted>")?(?(quoted).+?"|\S+\s) | "Dogs.jpg "Yiska playing.jpg"" 中的 Dogs.jpg 和 "Yiska playing.jpg" |
### 替換
替換是替換模式中使用的正則表達式。 下表列出了用于替換的字符:
| 字符 | 描述 | 模式 | 替換模式 | 輸入字符串 | 結果字符串 |
| --- | --- | --- | --- | --- | --- |
| **$**number | 替換按組 _number_ 匹配的子字符串。 | \b(\w+)(\s)(\w+)\b | $3$2$1 | "one two" | "two one" |
| **${**name**}** | 替換按命名組 _name_ 匹配的子字符串。 | \b(?< word1>\w+)(\s)(?< word2>\w+)\b | ${word2} ${word1} | "one two" | "two one" |
| **$** | 替換字符"$"。 | \b(\d+)\s?USD | $1 | "103 USD" | "$103" |
| **><** | 替換整個匹配項的一個副本。 | (\$*(\d*(\.+\d+)?){1}) | **>< | "$1.30" | "**$1.30**" |
| ** | 替換匹配前的輸入字符串的所有文本。 | B+ | "AABBCC" | "AAAACC" |
| **/tr>** | 替換匹配后的輸入字符串的所有文本。 | B+ | /tr> | "AABBCC" | "AACCCC" |
| **$+** | 替換最后捕獲的組。 | B+(C+) | $+ | "AABBCCDD" | AACCDD |
| **$_** | 替換整個輸入字符串。 | B+ | $_ | "AABBCC" | "AAAABBCCCC" |
### 雜項構造 下表列出了各種雜項構造:
| 構造 | 描述 | 實例 |
| --- | --- | --- |
| **(?imnsx-imnsx)** | 在模式中間對諸如不區分大小寫這樣的選項進行設置或禁用。 | \bA(?i)b\w+\b 匹配 "ABA Able Act" 中的 "ABA" 和 "Able" |
| **(?#comment)** | 內聯注釋。該注釋在第一個右括號處終止。 | \bA(?#Matches words starting with A)\w+\b |
| **#** [to end of line] | X 模式注釋。 該注釋以非轉義的 # 開頭,并繼續到行的結尾。 | (?x)\bA\w+\b#Matches words starting with A |
## Regex 類
Regex 類用于表示一個正則表達式。 下表列出了 Regex 類中一些常用的方法:
| 方法 | 描述 |
| --- | --- |
| **public bool IsMatch( string input )** | 指示 Regex 構造函數中指定的正則表達式是否在指定的輸入字符串中找到匹配項。 |
| **public bool IsMatch( string input, int startat )** | 指示 Regex 構造函數中指定的正則表達式是否在指定的輸入字符串中找到匹配項,從字符串中指定的開始位置開始。 |
| **public static bool IsMatch( string input, string pattern )** | 指示指定的正則表達式是否在指定的輸入字符串中找到匹配項。 |
| **public MatchCollection Matches( string input )** | 在指定的輸入字符串中搜索正則表達式的所有匹配項。 |
| **public string Replace( string input, string replacement )** | 在指定的輸入字符串中,把所有匹配正則表達式模式的所有匹配的字符串替換為指定的替換字符串。 |
| **public string[] Split( string input )** | 把輸入字符串分割為子字符串數組,根據在 Regex 構造函數中指定的正則表達式模式定義的位置進行分割。 |
如需了解 Regex 類的完整的屬性列表,請參閱微軟的 C# 文檔。
## 實例 1
下面的實例匹配了以 'S' 開頭的單詞:
```
using System;
using System.Text.RegularExpressions;
namespace RegExApplication
{
class Program
{
private static void showMatch(string text, string expr)
{
Console.WriteLine("The Expression: " + expr);
MatchCollection mc = Regex.Matches(text, expr);
foreach (Match m in mc)
{
Console.WriteLine(m);
}
}
static void Main(string[] args)
{
string str = "A Thousand Splendid Suns";
Console.WriteLine("Matching words that start with 'S': ");
showMatch(str, @"\bS\S*");
Console.ReadKey();
}
}
}
```
當上面的代碼被編譯和執行時,它會產生下列結果:
```
Matching words that start with 'S':
The Expression: \bS\S*
Splendid
Suns
```
## 實例 2
下面的實例匹配了以 'm' 開頭以 'e' 結尾的單詞:
```
using System;
using System.Text.RegularExpressions;
namespace RegExApplication
{
class Program
{
private static void showMatch(string text, string expr)
{
Console.WriteLine("The Expression: " + expr);
MatchCollection mc = Regex.Matches(text, expr);
foreach (Match m in mc)
{
Console.WriteLine(m);
}
}
static void Main(string[] args)
{
string str = "make maze and manage to measure it";
Console.WriteLine("Matching words start with 'm' and ends with 'e':");
showMatch(str, @"\bm\S*e\b");
Console.ReadKey();
}
}
}
```
當上面的代碼被編譯和執行時,它會產生下列結果:
```
Matching words start with 'm' and ends with 'e':
The Expression: \bm\S*e\b
make
maze
manage
measure
```
## 實例 3
下面的實例替換掉多余的空格:
```
using System;
using System.Text.RegularExpressions;
namespace RegExApplication
{
class Program
{
static void Main(string[] args)
{
string input = "Hello World ";
string pattern = "\\s+";
string replacement = " ";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(input, replacement);
Console.WriteLine("Original String: {0}", input);
Console.WriteLine("Replacement String: {0}", result);
Console.ReadKey();
}
}
}
```
當上面的代碼被編譯和執行時,它會產生下列結果:
```
Original String: Hello World
Replacement String: Hello World
```
- C# 基礎
- C# 簡介
- C# 環境
- C# 程序結構
- C# 基本語法
- C# 數據類型
- C# 類型轉換
- C# 變量
- C# 常量
- C# 運算符
- C# 判斷
- C# 循環
- C# 封裝
- C# 方法
- C# 可空類型(Nullable)
- C# 數組(Array)
- C# 字符串(String)
- C# 結構(Struct)
- C# 枚舉(Enum)
- C# 類(Class)
- C# 繼承
- C# 多態性
- C# 運算符重載
- C# 接口(Interface)
- C# 命名空間(Namespace)
- C# 預處理器指令
- C# 正則表達式
- C# 異常處理
- C# 文件的輸入與輸出
- C# 高級
- C# 特性(Attribute)
- C# 反射(Reflection)
- C# 屬性(Property)
- C# 索引器(Indexer)
- C# 委托(Delegate)
- C# 事件(Event)
- C# 集合(Collection)
- C# 泛型(Generic)
- C# 匿名方法
- C# 不安全代碼
- C# 多線程
- ASP.NET 簡介
- Web Pages 教程
- ASP.NET Web Pages - 教程
- ASP.NET Web Pages - 添加 Razor 代碼
- ASP.NET Web Pages - 頁面布局
- ASP.NET Web Pages - 文件夾
- ASP.NET Web Pages - 全局頁面
- ASP.NET Web Pages - HTML 表單
- ASP.NET Web Pages - 對象
- ASP.NET Web Pages - 文件
- ASP.NET Web Pages - 幫助器
- ASP.NET Web Pages - WebGrid 幫助器
- ASP.NET Web Pages - Chart 幫助器
- ASP.NET Web Pages - WebMail 幫助器
- ASP.NET Web Pages - PHP
- ASP.NET Web Pages - 發布網站
- Razor 教程
- ASP.NET Razor - 標記
- ASP.NET Razor - C# 和 VB 代碼語法
- ASP.NET Razor - C# 變量
- ASP.NET Razor - C# 循環和數組
- ASP.NET Razor - C# 邏輯條件
- ASP.NET Razor - VB 變量
- ASP.NET Razor - VB 循環和數組
- ASP.NET Razor - VB 邏輯條件
- MVC 教程
- ASP.NET MVC 教程
- ASP.NET MVC - Internet 應用程序
- ASP.NET MVC - 應用程序文件夾
- ASP.NET MVC - 樣式和布局
- ASP.NET MVC - 控制器
- ASP.NET MVC - 視圖
- ASP.NET MVC - SQL 數據庫
- ASP.NET MVC - 模型
- ASP.NET MVC - 安全
- ASP.NET MVC - HTML 幫助器
- ASP.NET MVC - 發布網站
- Web Forms 教程
- ASP.NET Web Forms - 教程
- ASP.NET Web Forms - HTML 頁面
- ASP.NET Web Forms - 服務器控件
- ASP.NET Web Forms - 事件
- ASP.NET Web Forms - HTML 表單
- ASP.NET Web Forms - 維持 ViewState
- ASP.NET Web Forms - TextBox 控件
- ASP.NET Web Forms - Button 控件
- ASP.NET Web Forms - 數據綁定
- ASP.NET Web Forms - ArrayList 對象
- ASP.NET Web Forms - Hashtable 對象
- ASP.NET Web Forms - SortedList 對象
- ASP.NET Web Forms - XML 文件
- ASP.NET Web Forms - Repeater 控件
- ASP.NET Web Forms - DataList 控件
- ASP.NET Web Forms - 數據庫連接
- ASP.NET Web Forms - 母版頁
- ASP.NET Web Forms - 導航
- Web Pages 參考手冊
- ASP.NET Web Pages - 類
- ASP.NET Web Pages - WebSecurity 對象
- ASP.NET Web Pages - Database 對象
- ASP.NET Web Pages - WebMail 對象
- ASP.NET Web Pages - 更多幫助器
- MVC - 參考手冊
- Web Forms 參考手冊
- ASP.NET Web Forms - HTML 服務器控件
- ASP.NET Web Forms - Web 服務器控件
- ASP.NET Web Forms - Validation 服務器控件
- 免責聲明