若只簡單匹配固定字串,則無需任何修飾符,例如:需要匹配字串 77
,則可直接寫:new Regex("77")
。
下邊例舉一下常用的符號:(知道下面這些,一般的正規表示式便可清晰異常)
符號 | 釋義 | 範例 1 | 範例 2 |
\ |
跳脫字元,互相轉換一個具有特殊功能的字元 和一個普通字元 |
希望在字串中至少有一個「\」,那麼正規表示式應該這麼寫:\\+ |
|
^......$ |
開始標記(^)和結束標記($),中間為具體內容 若沒有邊界,則表示匹配可在字元中匹配 |
/^AA$/【解析】字串‘AA’可匹配;‘AAA’不可匹配 |
/AA$/【解析】取消開始符號‘^’則‘AAA’可匹配,表示以‘AA’結尾 |
* 、 + 、 ? 指定匹配子表示式的次數 |
* : 零次或多次; |
+ : 一次或多次; |
? : 零次或一次 |
[xxxx]、[^xxxx] |
中括號,代表可選擇的字元集合,可為任意字元 加了 ^ 後,相反,不可選擇的字元集合 |
[qw12]【解析】代表出現(q、w、1、2)中的字元均滿足條件 [A-Za-z0-9]【解析】數位+26個英文字母 |
[^qw12]【解析】增加符號‘^’,意思與‘範例 1’中的意思相反,標識不能出現(q、w、1、2)中的字元 |
{m,n} |
大括號,匹配數量,代表可匹配 m~n 次連續字元, 另外‘,n’可省略 |
a{2}【解析】出現‘aa’,例如‘123aaf4’可匹配 | a{2,}【解析】匹配2~∞次字元‘a’,即aa、aaa、aaaa...... |
. |
匹配除「/n」之外的任何 單個字元 |
||
(pattern)、(?:pattern)、(?=pattern)、(?!pattern) |
(pattern):匹配 pattern 並獲取;(?:pattern):匹配但不獲取 |
(?=pattern):正向預查,在任何匹配 pattern 的字串開始處匹配查詢字串 | (?!pattern):負向預查,在任何不匹配 pattern 的字串開始處匹配查詢字串 |
(xxx){n} |
小括號,代表分組,即‘xxx’可出現 n 次 |
(12|34){2}【解析】匹配1212、1234、3412、3434 | |
xxx|xx | 豎線,選擇表示式 | 123|234【解析】代表匹配‘123’或者‘234’ | |
\數位 | 反斜線+數位,參照,數位代表參照前面第幾個捕獲分組 | <([a-z]+)><\/\1>【解析】參照第一個捕獲分組,可匹配‘<div></div>’ | |
\d \D | 匹配數位字元,0~9(相反 \D 代表非數位) | ||
\f \n \r | \f :匹配換頁符 | \n:匹配換行符 | \r:匹配回車符 |
\s \S | \s:匹配任何空白字元,包括空格、製表符、換頁符等 | \S:匹配任何非空白字元 | |
\w \W | \w:匹配包括下劃線的任何單詞字元,等價於:[A-Za-z0-9_] | \W:等價於:[^A-Za-z0-9_] | |
\t | 匹配一個製表符 |
出自程式集:System.Text.RegularExpressions.dll。
public static System.Text.RegularExpressions.Match Match (string input, string pattern);
public static System.Text.RegularExpressions.Match Match (string input, string pattern, RegexOptions options);
RegexOptions 列舉中常用的三個:
IgnoreCase 表示不區分輸入的大小寫;
IgnorePatternWhitespace 表示去掉模式中的非跳脫空白,並啟用由#標記的註釋;
RightToLeft 表示從右向左掃描、匹配,這時,靜態的Match方法返回從右向左的第一個匹配;
下邊是應用範例:(寫法一對應定義中的引數)
string inputstr = "ADDR=1234;NAME=ZHANG;PHONE=6789";
{// 寫法一
Match match1 = Regex.Match(inputstr, "NAME=(.+);");
string value1 = match1.Groups[1].Value;
// ZHANG;PHONE=6789;NAME=ZHENG
}
inputstr = "ADDR=1234;NAME=ZHANG;PHONE=6789;NAME=ZHENG;";
{// 寫法二
Regex reg = new Regex("NAME=(.+);");
Match match2 = reg.Match(inputstr);
string value2 = match2.Groups[1].Value;
// ZHANG
}
inputstr = "ADDR=1234;name=ZHANG;PHONE=6789";
{// 測試不區分大小寫
Match match3 = Regex.Match(inputstr, "NAME=(.+);", RegexOptions.IgnoreCase);
string value3 = match3.Groups[1].Value;
// ZHANG
Match match31 = Regex.Match(inputstr, "NAME=(.+);");
string value31 = match31.Groups[1].Value;
// ""
}
inputstr = "ADDR=1234;NAME=ZHANG;PHONE=6789";
{// 去掉模式中的非跳脫空白
Match match4 = Regex.Match(inputstr, " N A ME = (.+) ;", RegexOptions.IgnorePatternWhitespace);
string value4 = match4.Groups[1].Value; // pattern 中的空格在匹配時被忽略
// ZHANG
Match match41 = Regex.Match(inputstr, " N AME=(.+);");
string value41 = match41.Groups[1].Value;
// ""
}
inputstr = "ADDR=1234;NAME=ZHANG;;PHONE=6789;ADDR=1234;NAME=ZHANG;";
{// 從右向左掃描、匹配
Match match5 = Regex.Match(inputstr, ";NAME", RegexOptions.RightToLeft);
int value5 = match5.Groups[1].Index;
// 42
Match match51 = Regex.Match(inputstr, ";NAME");
int value51 = match51.Groups[1].Index;
// 9
}
Matchs 方法的匹配規則類似 Match,只是返回的為 MatchCollection。如下範例:
string line = "ADDR=1234;NAME=ZZHANG;NAME=ZZHENG;PHONE=6789;NAME=";
{
var matches = Regex.Matches(line, "NAME=(.{4})");
foreach(Match match in matches)
{
string value1 = match.Groups[1].Value;
// ZZHA
// ZZHE
}
}
以下是兩個常用的過載:
public static bool IsMatch (string input, string pattern);
public static bool IsMatch (string input, string pattern, System.Text.RegularExpressions.RegexOptions options);
此方法返回一個 bool,過載形式同靜態的 Matches,若輸入中匹配模式,返回 true,否則返回 false。
string inputstr = "ADDR=1234;NAME=ZZHANG;NAME=ZZHENG;PHONE=6789;NAME=";
{
var ismatch1 = Regex.IsMatch(inputstr, "NAME=(.{4})"); // true
var ismatch2 = Regex.IsMatch(inputstr, "NAME=(.{400})"); // false
}
在使用正規表示式前,需先參照名稱空間:
using System.Text.RegularExpressions;
傳入字串型別的金額進行判斷,若不是金額返回報錯提示:
string pattern = @"^([1-9]\d{0,9}|0)(\.\d{1,2})?$"; // 兩位小數
// 若需要匹配更多位數小數,則可修改「\d{1,2}」中的數位 2
if (!Regex.IsMatch(jine, pattern))
return "金額格式有誤,請重新輸入!" ;
解析:^([1-9]\d{0,9}|0)(\.\d{1,2})?$
小數點前:其中 ([1-9]\d{0,9}|0) 中的第一位「[1-9]」代表為 1~9 的數位;「\d{0,9}」 代表一串 0~9 的數位,不限位數;豎線「|」代表前後存在其一,後邊是 0,代表可以為小於 1 的小數。
小數點後:其中 (\.\d{1,2})? 問號表示此部分可省,第一位「[1-9]」代表為 1~9 的數位;「\d」代表數位,後邊的「{1,2}」表示有 1~2 位小數。
其他常用的數值模式:
0 或非 0 開頭的數位 | ^(0|[1-9][0-9]*)$ |
正整數 | ^[1-9]\d*$ |
浮點數 | ^(-?\d+)(\.\d+)?$ |
正數/負數/小數 | ^(\-|\+)?\d+(\.\d+)?$ |
郵箱地址分為兩個部分,@ 符號前和後。前一部分代表使用者名稱,後邊是電子郵件伺服器的域名。
使用者名稱:可以是字母、數位、點號、減號、下劃線,但必須以數位或字母開頭,3~18 個字元;
域名規範:只能使用英文字母(a~z,不區分大小寫)、數位(0~9)以及連線符(-);連線符(-)不能連續出現、單獨註冊,也不能放在開頭和結尾。
由於域名的種類太多了,因此本模組只簡單校驗以上條件。
string inputstr = "[email protected]";
{
var ismatch1 = Regex.IsMatch(inputstr, @"^([\w-\.]+)@([a-zA-Z0-9-\.]+)(\.[a-zA-Z0-9]+)$"); // true
inputstr = "[email protected]";
ismatch1 = Regex.IsMatch(inputstr, @"^((?!.*?\.\.)[\w-\.]+)@([a-zA-Z0-9-\.]+)(\.[a-zA-Z0-9]+)$"); // false
ismatch1 = Regex.IsMatch(inputstr, @"^((?!.*?--)[\w-\.]+)@([a-zA-Z0-9-\.]+)(\.[a-zA-Z0-9]+)$"); // true
inputstr = "[email protected]";
ismatch1 = Regex.IsMatch(inputstr, @"^((?!.*?(--|\.\.))[\w-\.]+)@((?!.*?(--|\.\.))[a-zA-Z0-9-\.]+)(\.[a-zA-Z0-9]+)$"); // false
ismatch1 = Regex.IsMatch(inputstr, @"^((?!.*?--)[\w-\.]+)@([a-zA-Z0-9-\.]+)(\.[a-zA-Z0-9]+)$"); // false
// 最後一個最為準確
ismatch1 = Regex.IsMatch(inputstr, @"^[a-zA-Z0-9]((?!.*?(\.\.|--))[a-zA-Z0-9\._-]){1,16}[a-zA-Z0-9]@([0-9a-zA-Z][0-9a-zA-Z-]{0,61}[0-9a-zA-Z]\.)+([0-9a-zA-Z][0-9a-zA-Z-]{0,61}[0-9a-zA-Z])$"); // true
}
由測試結果可以得出結論:
若想簡單判斷郵件格式,可以用這個:
^([\w-\.]+)@([a-zA-Z0-9-\.]+)(\.[a-zA-Z0-9]+)$
比較準確判斷的話,請用這個:
^[a-zA-Z0-9]((?!.*?(\.\.|--))[a-zA-Z0-9\._-]){1,16}[a-zA-Z0-9]@([0-9a-zA-Z][0-9a-zA-Z-]{0,61}[0-9a-zA-Z]\.)+([0-9a-zA-Z][0-9a-zA-Z-]{0,61}[0-9a-zA-Z])$
解析:首先是將長串分為多個小部分,如下:
// 正規表示式詳解
^
[a-zA-Z0-9] // 使用者名稱首位
((?!.*?(\.\.|--))[a-zA-Z0-9\._-]){1,16}
[a-zA-Z0-9] // 使用者名稱末位
@
([0-9a-zA-Z] // .分隔的前邊 n 段域名的首位
[0-9a-zA-Z-]{0,61}
[0-9a-zA-Z]\.)+
([0-9a-zA-Z] // .分隔的最後一段域名的首位
[0-9a-zA-Z-]{0,61}
[0-9a-zA-Z]) // .分隔的最後一段域名的末位
$
IP 的規則很簡單,就是:第一位和最後一位數位不能是 0 或 255。
允許 0 補位的模式:^(25[0-4]|2[0-4]\d]|[01]?\d{2}|[1-9])\.(25[0-5]|2[0-4]\d]|[01]?\d?\d)\.(25[0-5]|2[0-4]\d]|[01]?\d?\d)\.(25[0-4]|2[0-4]\d]|[01]?\d{2}|[1-9])$
^
(25[0-4] // 250~254
|2[0-4]\d] // 200~249
|[01]?\d{2} // 10~199
|[1-9] // 1~9
)
\.(25[0-5]|2[0-4]\d]|[01]?\d?\d)
\.(25[0-5]|2[0-4]\d]|[01]?\d?\d)
\.(25[0-4]|2[0-4]\d]|[01]?\d{2}|[1-9])
$
不允許 0 補位的模式:^(25[0-4]|2[0-4]\d]|1\d{2}|[1-9]\d|[1-9])\.(25[0-5]|2[0-4]\d]|1\d{2}|[1-9]\d|[0-9])\.(25[0-5]|2[0-4]\d]|1\d{2}|[1-9]\d|[0-9])\.(25[0-4]|2[0-4]\d]|1\d{2}|[1-9]\d|[1-9])$
^
(25[0-4] // 250~254
|2[0-4]\d] // 200~249
|1\d{2} // 100~199
|[1-9]\d // 10~99
|[1-9] // 1~9
)
\.(25[0-5]|2[0-4]\d]|1\d{2}|[1-9]\d|[0-9])
\.(25[0-5]|2[0-4]\d]|1\d{2}|[1-9]\d|[0-9])
\.(25[0-4]|2[0-4]\d]|1\d{2}|[1-9]\d|[1-9])
$
3 位或 4 位區號;區號可以用小括號括起來;區號可以省略;區號與本地號間可以用減號或空格隔開;本地號首位不為 0;可以有3位數的分機號,分機號前要加減號。
string inputstr = "(0290)-89898989-666";
{
var ismatch1 = Regex.IsMatch(inputstr, @"^((\(0\d{2,3}\)|0\d{2,3})[- ])?[1-9]\d{7}(-\d{3})?$"); // true
}
最佳的模式:^((\(0\d{2,3}\)|0\d{2,3})[- ])?[1-9]\d{7}(-\d{3})?$
^
(
(\(0\d{2,3}\) // 允許區號用小括號包裹
|0\d{2,3})
[- ] // 區號和本機號用 - 或空格隔開
)?
[1-9]\d{7}
(-\d{3})?
$
本次只識別國內的電話號碼,國際區號為 (+86),可以整體省略,也可以單獨去掉加號或括號。
在根據國內最新的手機號編碼進行測試:
string inputstr = "17797797997";
var ismatch1 = Regex.IsMatch(inputstr, @"^((\+)?86|\((\+)?86\))?1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$"); // true
經測試得出如下模式:
^((\+)?86|\((\+)?86\))?1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$
^
((\+)?86|\((\+)?86\))? // 是否新增國際區號
1 // 1 開頭
(
3[0-9]
|4[01456879]
|5[0-35-9]
|6[2567]
|7[0-8]
|8[0-9]|
9[0-35-9])
\d{8} // 後八位隨機
$
手機號的最新編碼,參考: 手機號驗證最新正規表示式
以數位 0 開頭的郵編是存在的,比如內蒙古自治區呼和浩特市的 010000,所以對於郵編的六位,沒有區別。
因此,郵編的模式就是:
^\d{6}$
測試只包含域名地址:
string inputstr = "https://www.baidu.com/?tn=88093251_72_hao_pg";
var ismatch1 = Regex.IsMatch(inputstr, @"^((file|gopher|news|nntp|telnet|ftp|http|https|ftps|sftp)://)?(www\.)?(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6}))(/[a-zA-Z0-9\&%_\./-~-]*)?$"); // true
測試可用的模式為:
^((file|gopher|news|nntp|telnet|ftp|http|https|ftps|sftp)://)?(www\.)?(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6}))(/[a-zA-Z0-9\&%_\./-~-]*)?$
解析:
^
((file|gopher|news|nntp|telnet|ftp|http|https|ftps|sftp)://)?
(www\.)?([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})
(/[a-zA-Z0-9\&%_\./-~-]*)?
$
注:其中第三行表示的是域名地址,可以參考本章節中的「3. IPv4」將 IP 地址相容。
身份證號的規則:
地址碼:長度 6 位,以不為 0 的數位開頭。即:^[1-9]\d{5}$。
年份:一般以 18、19、20 開頭,即:^(18|19|20)\d{2}$。
月份:1~9 月需要補 0 ,即:^((0[1-9])|(1[0-2]))$。
日期:1~31 ,即^((0[1-9]|[1-2][0-9])|30|31)$。
順序碼:3 位數位,即:^\d{3}$。
校驗碼:1位數位或字母X或x,即^[0-9Xx]$。
// 測試
string inputstr = "11010519491231002X";
var ismatch1 = Regex.IsMatch(inputstr, @"^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))((0[1-9]|[1-2][0-9])|30|31)\d{3}[0-9Xx]$"); // true
測試結果:
^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))((0[1-9]|[1-2][0-9])|30|31)\d{3}[0-9Xx]$
參考: 身份證號碼的正規表示式及驗證詳解
經度:-180.0~+180.0(整數部分為 0~180,必須輸入 1 到 5 位小數)
^[\-\+]?(0?\d{1,2}\.\d{1,5}|1[0-7]?\d{1}\.\d{1,5}|180\.0{1,5})$
^
[-\+]?
(
0?\d{1,2}\.\d{1,5}
|1[0-7]?\d{1}\.\d{1,5}
|180\.0{1,5} // 可代表 180.00000
)
緯度:-90.0~+90.0(整數部分為 0~90,必須輸入 1 到 5 位小數)
^[\-\+]?([0-8]?\d{1}\.\d{1,5}|90\.0{1,5})$
^
[-\+]?
(
[0-8]?\d{1}\.\d{1,5}
|90\.0{1,5} // 可代表:90.00000
)
$
注:暫時整理這些,歡迎補充和指正。