1. 為什麼使用正則表達式? 典型的搜索和替換操作要求您提供與預期的搜索結果匹配的確切文本。雖然這種技術對於對靜態文本執行簡單搜索和替換任務可能已經足夠了,但它缺乏靈活性,若採用這種方法搜索動態文本,即使不是不可能,至少也會變得很困難。通過使用正則表達式,可以: ※ 測試字元串內的模式。 例如,可以 ...
1. 為什麼使用正則表達式?
典型的搜索和替換操作要求您提供與預期的搜索結果匹配的確切文本。雖然這種技術對於對靜態文本執行簡單搜索和替換任務可能已經足夠了,但它缺乏靈活性,若採用這種方法搜索動態文本,即使不是不可能,至少也會變得很困難。通過使用正則表達式,可以:
※ 測試字元串內的模式。
例如,可以測試輸入字元串,以查看字元串內是否出現電話號碼模式或信用卡號碼模式。這稱為數據驗證。
※ 替換文本。
可以使用正則表達式來識別文檔中的特定文本,完全刪除該文本或者用其他文本替換它。
※ 基於模式匹配從字元串中提取子字元串。
可以查找文檔內或輸入域內特定的文本。
2. 定義正則表達式的各種類別的字元、運算符和結構
※ 字元轉義
轉義字元 |
描述 |
模式 |
匹配 |
\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 之外的任何單個字元匹配。 |
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 |
與任何空白字元匹配。(匹配任何不可見字元,包括空格、製表符、換頁符等等。等價於[ \f\n\r\t\v]。) |
\w\s |
"ID A1.3" 中的 "D " |
\S |
與任何非空白字元匹配。 |
\s\S |
"int _ ctr" 中的 " c" |
\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(非字母數字)字元之間的邊界上。(匹配一個單詞邊界,也就是指單詞和空格間的位置(即正則表達式的“匹配”有兩種概念,一種是匹配字元,一種是匹配位置,這裡的\b就是匹配位置的)) |
er\b |
可以匹配“never”中的“er”,但不能匹配“verb”中的“er” |
\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" 中的 "99"、"50"和 "05" |
(?< ! 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" |
※ 備用構造
備用構造 |
描述 |
模式 |
匹配 |
| |
匹配以豎線 (|) 字元分隔的任何一個元素。 |
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" |
※
3. Regex 類常用方法
序號 |
方法 & 描述 |
1 |
public bool
IsMatch( string input ) |
2 |
public bool
IsMatch( string input, int startat ) |
3 |
public static
bool IsMatch( string input, string pattern ) |
4 |
public static
MatchCollection Matches(string input, string pattern) |
5 |
public string
Replace( string input, string replacement ) |
6 |
public
string[] Split( string input ) |