2013年12月31日 星期二

正規化Regex學習筆記

下面將使用
System.Text.RegularExpressions命名空間
中的Regex類別

第一個範例
匹配下列格式的數字
xxx-xxxxxxxx
所謂數字意旨"0~9" 格式包含"-"字號
比如246-81012141 合格
比如 AS1-AS865412 不合格
因為英文不是數字

ok! 了解目的之後 來看程式碼吧


假如在textBox1.Text輸入字串
按下button1將會執行以下程序

private void button1_Click(object sender, EventArgs e)
{
//進入if判斷 並傳值呼叫
if (!IsTelephone(textBox1.Text))//驗證電話號碼格式是否正確
{
MessageBox.Show("電話號碼格式不正確"); //彈出消息對話框
}
else
{
MessageBox.Show("電話號碼格式正確"); //彈出消息對話框
}
}
/// <summary>
/// 驗證電話號碼格式是否正確
/// </summary>
/// <param name="str_telephone">電話號碼訊息</param>
/// <returns>方法返回布爾值</returns>
public bool IsTelephone(string str_telephone)//副程式將傳會 bool
{
//驗證str_telephone字串是否符合規定,IsMatch方法將回傳bool
return System.Text.RegularExpressions.//使用正則表達式判斷是否匹配
Regex.IsMatch(str_telephone, @"^(\d{3,4}-)?\d{6,8}$");
}

以上使用了Regex.IsMatch 方法 (String)返回是一個bool
將決定if判斷show出哪一個訊息!!

而@"^(\d{3,4}-)?\d{6,8}$"

0.
^ 代表比對開始
1.
C# 字串前的 @ 代表把字串中的 '\' 當成一般字元處理
2.
() 群組的意思 比如(ab) 能匹配 abc 中的 ab
3.
\d代表著0~9數字
4.
{3,4} 代表至少3個數字,最多4個數字
5.
- 代表匹配-號
6.
? 匹配前面的子運算式零次或一次。
例如:Gooo?gle 只能匹配 Gooogle 和 Google。
? 等於 {0,1}
7.
\d{6,8} 數字0~9 至少6個字最多8個字
8.
$代表比對結束

所以 將會比對 3~4的數字 與"-"號最後是6~8的數字 格式如下
XXX-XXXXXX

XXXX-XXXXXXXX




第二個範例
匹配帳號密碼如下
A~Z a~z 與 0~9

當user 在textBox1.Text輸入密碼時
按下BUTTON1將進入以下程序

private void button1_Click(object sender, EventArgs e)
{
//Trim()意思是
//從目前字串的開頭和結尾移除所有空白字元後
//所保留下來的字串。
if (!IsPassword(textBox1.Text.Trim()))//驗證密碼格式是否正確
{ MessageBox.Show("密碼格式不正確!!!"); }//彈出消息對話框
else { MessageBox.Show("密碼格式正確!!!!!"); }//彈出消息對話框
}
/// <summary>
/// 驗證碼碼輸入條件
/// </summary>
/// <param name="str_password">密碼字串</param>
/// <returns>返回布爾值</returns>
public bool IsPassword(string str_password)
{
return System.Text.RegularExpressions.//使用正則表達式判斷是否匹配
Regex.IsMatch(str_password, @"[A-Za-z]+[0-9]");
}


程式碼與第一範例雷同
不同得是正規化 運算是的部分
1.
[] 字元範圍
2.
A-Z 代表大寫A~Z
3.
a-z 代表小寫a~z
4.
+ 代表匹配一次 或 多次
例如:Gooo+gle 能匹配 Gooogle、Goooooogle,但不能匹配 Google
5.
[0-9] 代表匹配0~9的字元範圍






第三個範例
郵政編號
由六個數字組成

不多說直接看下列程式碼
因為與上面兩個範例一樣
不同於正規畫運算式

private void button1_Click(object sender, EventArgs e)
{
if (!IsPostalcode(textBox1.Text))//驗證郵編格式是否正確
{ MessageBox.Show("郵政編號不正確!!!"); }//彈出消息對話框
else { MessageBox.Show("郵政編號正確!!!!!"); }//彈出消息對話框
}
/// <summary>
/// 驗證郵編格式是否正確
/// </summary>
/// <param name="str_postalcode">郵編字串</param>
/// <returns>返回布爾值</returns>
public bool IsPostalcode(string str_postalcode)
{
return System.Text.RegularExpressions.//使用正則表達式判斷是否匹配
Regex.IsMatch(str_postalcode, @"^\d{6}$");
}

來看一下
1.
開始比對
2.
\d 比對數字0~9
3.
{6} 前面是/d 代表六個數字
4.
$比對結束




範例四
驗證手機
注意 此驗證並不是正確格式
目的只是讓讀者快速複習
正規化運化式!

來看程式碼如下
{
if (!IsHandset(textBox1.Text))//驗證手機號是否正確
{ MessageBox.Show("手機號不正確!!!"); }//彈出消息對話框
else { MessageBox.Show("手機號正確!!!!!"); }//彈出消息對話框
}
/// <summary>
/// 驗證手機號是否正確
/// </summary>
/// <param name="str_handset">手機號碼字串</param>
/// <returns>返回布爾值</returns>
public bool IsHandset(string str_handset)
{
return System.Text.RegularExpressions.Regex.////使用正則表達式判斷是否匹配
IsMatch(str_handset, @"^[0][3-5]\d{8}$");
}

無須解釋! 程式如前幾個範例相同
不同於正規畫運算式 解釋下
"^[0][3-5]\d{8}$"

1.
^比對開頭
2.
[0]比對數字0 一個
3.
[3-5] 比對數字3 4 5其中一個
4.
\d 比對數字0~9
5.
{8} 比對8個數字
6.
$結束比對




範例五
驗證身份證字號
注意此身分證之號
不復合現實的格式 目標只用於學習

private void button1_Click(object sender, EventArgs e)
{
if (!IsIDcard(textBox1.Text.Trim()))//驗證身份證號是否正確
{ MessageBox.Show("身份證號不正確!!!"); }//彈出消息對話框
else { MessageBox.Show("身份證號正確!!!!!"); }//彈出消息對話框
}
/// <summary>
/// 驗證身份證號是否正確
/// </summary>
/// <param name="str_idcard">身份證號字串</param>
/// <returns>返回布爾值</returns>
public bool IsIDcard(string str_idcard)
{
return System.Text.RegularExpressions.Regex.//使用正則表達式判斷是否匹配
IsMatch(str_idcard, @"(^\d{10}$)|(^\d{15}$)");
}

正規化運算式如下
1.
^開始比對
2.
\d比對數字
3.
{10} 比對10個數字
4.
$比對結束
5.
() 代表一個群組
6.
| 或的意思 A|B 代表 A或B 其中一個就算成立
7.
後面不多說了 因為與1~6 都一樣




範例六
驗證兩位小數
3.74 6.77 798.11 10.11等等...
來看程式範例

private void button1_Click(object sender, EventArgs e)
{
if (!IsDecimal(txt_Value.Text.Trim()))//驗證小數是否正確
{ MessageBox.Show("請輸入兩位小數!!!", "提示"); }//彈出消息對話框
else { MessageBox.Show("輸入正確!!!!!", "提示"); }//彈出消息對話框
}
/// <summary>
/// 驗證小數是否正確
/// </summary>
/// <param name="str_decimal">小數字串</param>
/// <returns>返回布爾值</returns>
public bool IsDecimal(string str_decimal)
{
return System.Text.RegularExpressions.Regex.//使用正則表達式判斷是否匹配
IsMatch(str_decimal, @"^[0-9]+(.[0-9]{2})?$");
}

正規化運算式 說明如下
1.
[0-9] 代表0~9其中一個
2.
+ 代表 1個或多個 [0-9]

3.
() 代表群組
4.
"." 是一個點 因為字串""外有加@ 所以不用打\.
5.
[0-9] 0到9的數字
6.
{2} 代表只能有個0~9數字
7.
()群組
8.
? 可匹配 0次 或一次 比如
abc?可以 ab 或 abc 可有 可無
9.
$結束比對!




範例七
比對一年中
1~12月份

來看下列程式碼

private void btn_Validate_Click(object sender, EventArgs e)
{
if (!IsMonth(textBox1.Text.Trim()))//驗證月份是否正確
{
MessageBox.Show("輸入月份不正確!!!", "提示");
}
else
{
MessageBox.Show("輸入訊息正確!!!!!", "提示");
}
}
/// <summary>
/// 驗證月份是否正確
/// </summary>
/// <param name="str_Month">月份訊息字串</param>
/// <returns>返回布爾值</returns>
public bool IsMonth(string str_Month)
{
return System.Text.RegularExpressions.Regex.//使用正則表達式判斷是否匹配
IsMatch(str_Month, @"^(0?[[1-9]|1[0-2])$");
}


1.
^開始比對
2.
()群組
3.
0數字0
4.
? 比對前面那個數字0 一次 或0次,可有可無
5.
[1-9] 代表比對一個 1~9的數字
6.
| 或者是
7.
1 比對一個數字1
8.
[0-2] 比對一個0~2的數字
9.
$ 比對結束

範例八
使用正規化 驗證 一個月1號~31號

來看程式碼
private void btn_Validate_Click(object sender, EventArgs e)
{
if (!IsDay(textBox1.Text.Trim()))//驗證每月的31天
{ MessageBox.Show("輸入天數不正確!!!", "提示"); }//彈出消息對話框
else { MessageBox.Show("輸入訊息正確!!!!!", "提示"); }//彈出消息對話框
}
/// <summary>
/// 驗證每月的31天
/// </summary>
/// <param name="str_day">每月的天數</param>
/// <returns>返回布爾值</returns>
public bool IsDay(string str_day)
{
return System.Text.RegularExpressions.Regex.//使用正則表達式判斷是否匹配
IsMatch(str_day, @"^((0?[1-9])|((1|2)[0-9])|30|31)$");
}

1.
^ 開始比對
2.
()群組
3.
0將比對數字0
4.
? 比對前面的數字0 0次或1次
5.
[1-9] 比對一個1~9的數字
6.
| 或
7.
()群組
8.
(1|2) 比對1或2 的數字一個
9.
[0-9] 比對數字0~9 一次
10.
|或者
11.
30 比對30
12.
31比對31
13.
$ 比對結束



範例八
比對多個數字

來看下列範例
private void button1_Click(object sender, EventArgs e)
{
if (!IsNumber(textBox1.Text.Trim()))//驗證輸入是否為數字
{ MessageBox.Show("只充許輸入數字!!!", "提示"); }//彈出消息對話框
else { MessageBox.Show("輸入訊息正確!!!!!", "提示"); }//彈出消息對話框
}
/// <summary>
/// 驗證輸入是否為數字
/// </summary>
/// <param name="str_number">用戶輸入的字串</param>
/// <returns>方法返回布爾值</returns>
public bool IsNumber(string str_number)
{
return System.Text.RegularExpressions.Regex.//使用正則表達式判斷是否匹配
IsMatch(str_number, @"^[0-9]*$");
}

1.
^開始比對
2.
[0-9] 比對0~9數字
3.
* 比多0個或多個數字
4.
$比對結束





範例九
使用正規化 驗證密碼 長度
6位數到18位數

程式碼如下

private void button1_Click(object sender, EventArgs e)
{
if (!IsPasswLength(textBox1.Text.Trim()))//驗證密碼長度是否正確
{
MessageBox.Show("密碼長度不正確\n" +//彈出消息對話框
"密碼長度為6-18位!!!", "提示");
}
else { MessageBox.Show("輸入訊息正確!!!!!", "提示"); }//彈出消息對話框
}
/// <summary>
/// 驗證密碼長度是否正確
/// </summary>
/// <param name="str_Length">密碼字串</param>
/// <returns>方法返回布林值</returns>
public bool IsPasswLength(string str_Length)
{
return System.Text.RegularExpressions.Regex.//使用正規化運算式判斷是否符合
IsMatch(str_Length, @"^\d{6,18}$");
}

1.
^開始比對
2.
\d比對數字0~9
3.
{6,18}比對數字最少6位到18位
4.
$比對結束




範例十
驗證非0的正整數
1~無限
但是就是不能是0

程式如下
private void button1_Click(object sender, EventArgs e)
{
if (!IsIntNumber(textBox1.Text.Trim()))//驗證輸入是否為非零正整數
{ MessageBox.Show("只充許輸入非零的正整數!!!", "提示"); }//彈出消息對話框
else { MessageBox.Show("輸入訊息正確!!!!!", "提示"); }//彈出消息對話框
}
/// <summary>
/// 驗證輸入是否為非零正整數
/// </summary>
/// <param name="str_intNumber">用戶輸入的數值</param>
/// <returns>方法返回布林值</returns>
public bool IsIntNumber(string str_intNumber)
{
return System.Text.RegularExpressions.Regex.//使用正規化運算式判斷是否符合
IsMatch(str_intNumber, @"^\+?[1-9][0-9]*$");
}

1.
^開始比對
2.
\+ 比對一個正號
3.
?比對0個或1個
4.
[1-9]比對一個1~9的數字
5.
[0-9]比對一個0~9的數字
6.
*0個或多個
7.
$比對結束



範例十一
驗證非0的副整數

程式碼如下


private void button1_Click(object sender, EventArgs e)
{
if (!IsIntNumber(textBox1.Text.Trim()))//驗證輸入是否為非零負整數
{ MessageBox.Show("只充許輸入非零的負整數!!!", "提示"); }//彈出消息對話框
else { MessageBox.Show("輸入訊息正確!!!!!", "提示"); }//彈出消息對話框
}
/// <summary>
/// 驗證輸入是否為非零負整數
/// </summary>
/// <param name="str_intNumber">用戶輸入的數值</param>
/// <returns>方法返回布林值</returns>
public bool IsIntNumber(string str_intNumber)
{
return System.Text.RegularExpressions.Regex.//使用正規劃運算式判斷是否符合
IsMatch(str_intNumber, @"^\-[1-9][0-9]*$");
}

1.
^開始比對
2.
\-比對負號
3.
[1-9]比對1~9
4.
[0-9]比對0~9
5.
*比對0個或多個
6.
$比對結束


範例十二
驗證大寫字符

private void button1_Click(object sender, EventArgs e)
{
if (!IsUpChar(textBox1.Text.Trim()))//驗證輸入字符是否為大寫字母
{ MessageBox.Show("只充許輸入大寫字母!!!", "提示"); }//彈出消息對話框
else { MessageBox.Show("輸入訊息正確!!!!!", "提示"); }//彈出消息對話框
}
/// <summary>
/// 驗證輸入字符是否為大寫字母
/// </summary>
/// <param name="str_UpChar">用戶輸入的字串</param>
/// <returns>方法返回布林值</returns>
public bool IsUpChar(string str_UpChar)
{
return System.Text.RegularExpressions.Regex.//使用正規化運算式判斷是否符合
IsMatch(str_UpChar, @"^[A-Z]+$");
}

1.
^開始比對
2.
[A-Z]比對A~Z大寫英文字母
3.
+比對一個或多個英文字母
4.
$比對結束


範例十三
使用正規化驗證小寫字母

範例如下


private void button1_Click(object sender, EventArgs e)
{
if (!IsUpChar(textBox1.Text.Trim()))//驗證輸入字符是否為小寫字母
{ MessageBox.Show("只充許輸入小寫字母!!!", "提示"); }//彈出消息對話框
else { MessageBox.Show("輸入訊息正確!!!!!", "提示"); }//彈出消息對話框
}
/// <summary>
/// 驗證輸入字符是否為小寫字母
/// </summary>
/// <param name="str_UpChar">用戶輸入的字串</param>
/// <returns>方法返回布林值</returns>
public bool IsUpChar(string str_UpChar)
{
return System.Text.RegularExpressions.Regex.//使用正規化運算式判斷是否匹配
IsMatch(str_UpChar, @"^[a-z]+$");
}


1.
^開始比對
2.
[a-z]比對小寫a~z
3.
+比對1個或多個
4.
$比對結束





範例十四
比對字串中一樣的單字

private void button1_Click(object sender, EventArgs e)
{
System.Text.RegularExpressions.MatchCollection matches =//使用正規化運算式搜尋重複出現單詞的集合
System.Text.RegularExpressions.Regex.Matches(label1.Text,
@"\b(?<word>\w+)\s+(\k<word>)\b", System.Text.
RegularExpressions.RegexOptions.Compiled | System.Text.
RegularExpressions.RegexOptions.IgnoreCase);
if (matches.Count != 0)//如果集合中有內容
{
foreach (System.Text.RegularExpressions.Match//深度搜尋集合
match in matches)
{
string word = match.Groups["word"].Value;//取得重複出現的單詞
MessageBox.Show(word.ToString(), "英文單詞");//彈出消息對話框
}
}
else { MessageBox.Show("沒有重複的單詞"); }//彈出消息對話框
}
private void Form1_Load(object sender, EventArgs e)
{
label1.Text =//建立字串物件
"The the quick brown fox fox jumped over the lazy dog dog.";
}
}

本範例與之前的不同 使用了
Regex.Matches 方法
語法如下
publicstatic MatchCollection Matches
(
string input,
string pattern,
RegexOptions options
)

參數

input
型別:System.String
用來搜尋比對的字串。
pattern
型別:System.String
要比對的規則運算式模式。
options
型別:System.Text.RegularExpressions.RegexOptions
列舉值的位元組合,這些值會指定用於比對的選項。

傳回值

型別:System.Text.RegularExpressions.MatchCollection
搜尋之後找到的 Match 物件集合。如果找不到相符的項目,此方法會傳回空集合物件。


要注意的是 這傳回值是System.Text.RegularExpressions.MatchCollection

所以程式碼才會重System,text,regularExpressions.MatchCollection中調用

來看程式碼第一行
System.Text.RegularExpressions.MatchCollection matches
我們宣告了一個System.Text.RegularExpressions 命名空間
中的MatchCollection類別 叫做matches

第二行 matches=System.Text.RegularExpressions.Regex.Matches(參數1,參數2,參數3)
回傳Regex類中的Matches方法

接下來來說明這參數1.參數2.參數3

看到
參數1是 label1.Text
而這label1.Text等於這個字串
"The the quick brown fox fox jumped over the lazy dog dog."



再來
參數2
@"\b(?<word>\w+)\s+(\k<word>)\b"

1.\b 開始字緣比較



2.(?<word>\w+)

?比對子字串
w+比對一個或多個文字字元。將此擷取群組命名為Word
ps:Word可以自己取名

3.\s 比對空白鍵

4.\k<word>)
比對群組名為Word 之擷取群組中的字串。
5.\b
決定字組字元後面\k<word>) 是否與(?<word>\w+) 匹配成功
結束比對


第三參數 RegexOptions
Compiled | .IgnoreCase
但使用不同 RegexOptions 值來具現化。第一個規則運算式不會區分大小寫,在判斷某個字是否與前一個字相同時會忽略大小寫。

如果把IgnoreCase去掉 只剩下Compiled 將不會區分大小寫
如果把Compiled 去掉 只剩下IgnoreCase將會區分大小寫
如果第三參數不打 他也不會分辨大小寫


接下來 Regex.matchew 方法再回傳給 MatchCollection類別
關於MatchCollection類 注意MSDN這句話

該集合是不變的 (唯讀),而且沒有公用建構函式。Regex.Matches 方法會傳回 MatchCollection 物件。
集合中包含零個或多個 System.Text.RegularExpressions.Match 物件。如果比對成功,則會為每個在輸入字串中找到的符合項目將一個 System.Text.RegularExpressions.Match 物件填入集合中。如果比對失敗,則集合沒有包含 System.Text.RegularExpressions.Match 物件,且其 Count 屬性等於零。

繼續看下去!

並且使用MatchCollection的Count 看使否有讀取到
if (matchess.Count != 0) 來判斷matchess是否有搜尋到
如果有的話
foreach (System.Text.RegularExpressions.Match//深度搜尋集合
match in matchess)
關於Match使用方法msdn有清楚的解釋了
表示單一規則運算式 (Regular Expression) 比對的結果。
所以我們將matchess
使用 C# 中的 foreach 建構或 如果模式比對成功,Value 屬性會包含相符的子字串Visual Basic 中的 For Each 建構逐一查看集合。
如果模式比對成功,Value 屬性會包含相符的子字串
而 這裡有關於Match的使用方法


再來看foreach 中的輸出結果
string word = match.Groups["word"].Value;//取得重複出現的單詞
MessageBox.Show(word.ToString(), "英文單詞");//彈出消息對話框

注意mtach.Groups方法中 word表示群祖名,而Valie表示值
msdn中有清楚範例

比對失敗將進入else 程式區塊中






範例十五

使用正規化來替換文字
比如
1a2b3c4d5e
替換字元O
結果將會是
1o2o3o4o5o

注意 只替換 英文


來看程式碼吧
private void button1_Click(object sender, EventArgs e)
{
string strResult = System.Text.RegularExpressions.Regex.//使用正規化運算式替換字串
Replace(textBox1.Text, @"[A-Za-z]\*?", textBox2.Text);
MessageBox.Show("替換前字符:" + "\n" + textBox1.Text +//彈出消息對話框
"\n" + "替換的字符:" + "\n" + textBox2.Text + "\n" +
"替換後的字符:" + "\n" + strResult, "替換");
}
private void button2_Click(object sender, EventArgs e)
{
Close();//關閉視窗
}

這邊將使用Regex類別中的Replace中的方法
textBox1.tex 表示原文
再來是pattern
@"[A-Za-z]\*?"
大小寫A~Z \比對0次或多次 ?比對0次或一次

然後再SHOW出!!


範例十六
過濾字串
比如1a2b3c4d
過濾後變成
abcd
來看程式碼

private void btn_Split_Click(object sender, EventArgs e)
{
string[] P_Str = System.Text.RegularExpressions.//使用正規化運算式根據數字進行拆分
Regex.Split(txt_Split.Text, "[1-9]");
foreach (string s in P_Str)//深度搜尋拆分後的字串集合
{
txt_Result.Text += s;//顯示字串
}
}
private void btn_Close_Click(object sender, EventArgs e)
{
Application.Exit();//退出應用程式
}

本範例 簡單明瞭無須解釋
但要注意一點 Split 回傳 字串陣列




範例十七

判斷是否為英文字母

範例如下
private void btn_Validate_Click(object sender, EventArgs e)
{
if (!IsLetter(textBox1.Text.Trim()))//驗證字串是否為大小寫字母組成
{ MessageBox.Show("輸入的不是字母!!!", "提示"); }//彈出消息對話框
else { MessageBox.Show("輸入的是字母!!!!!", "提示"); }//彈出消息對話框
}
/// <summary>
/// 驗證字串是否為大小寫字母組成
/// </summary>
/// <param name="str_Letter">字串</param>
/// <returns>方法返回布林值</returns>
public bool IsLetter(string str_Letter)
{
return System.Text.RegularExpressions.Regex.//使用正規化運算式判斷是否匹配
IsMatch(str_Letter, @"^[A-Za-z]+$");
}

無須解釋 很基礎的範例


範例十八

如何驗證是否為中文字

程式如下
private void btn_Validate_Click(object sender, EventArgs e)
{
if (!IsChinese(textBox1.Text.Trim()))//驗證字串是否為中文字
{ MessageBox.Show("輸入的不是中文!!!", "提示"); }//彈出消息對話框
else { MessageBox.Show("輸入正確!!!!!", "提示"); }//彈出消息對話框
}
/// <summary>
/// 驗證字串是否為中文字
/// </summary>
/// <param name="str_chinese">字串</param>
/// <returns>方法返回布林值</returns>
public bool IsChinese(string str_chinese)
{
return System.Text.RegularExpressions.Regex.//使用正規化運算式判斷是否匹配
IsMatch(str_chinese, @"^[\u4e00-\u9fa5],{0,}$");
}


填入unicode 也一樣行得通喔
如果要驗證 字元是否數字組成 Char 中的 isDigit 搭配for深度搜尋即可




範例十九

驗證輸入是否大於7碼
不用if+ length >8 的話
正規化也一樣做得到

範例如下
private void btn_Validate_Click(object sender, EventArgs e)
{
if (!IsLength(textBox1.Text.Trim()))//驗證輸入字串中的字符數量是否大於7個
{ MessageBox.Show("至少輸入8個字符!!!", "提示"); }//彈出消息對話框
else { MessageBox.Show("輸入正確!!!!!", "提示"); }//彈出消息對話框
}
/// <summary>
/// 驗證輸入字串中的字符數量是否大於7個
/// </summary>
/// <param name="str_Length">字串</param>
/// <returns>方法返回布林值</returns>
public bool IsLength(string str_Length)
{
return System.Text.RegularExpressions.Regex.//使用正規化運算式判斷是否匹配
IsMatch(str_Length, @"^.{8,}$");
}

. 比對除了換行符號的任意字符
{8,} 至少8碼


範例十九
網路驗證技巧,驗證EMAIL
範例如下

 private void btn_Validate_Click(object sender, EventArgs e)
        {
            if (!IsEmail(textBox1.Text))//驗證Email格式是否正確
            { MessageBox.Show("Email格式錯誤!"); }//彈出消息對話框
            else { MessageBox.Show("Email格式正確!"); }//彈出消息對話框
        }
        /// <summary>
        /// 驗證Email格式是否正確
        /// </summary>
        /// <param name="str_Email">Email地址字串</param>
        /// <returns>方法返回布林值</returns>
        public bool IsEmail(string str_Email)
        {
            return System.Text.RegularExpressions.Regex.IsMatch(str_Email,//使用正規化運算式判斷是否匹配
@"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})$");
        }

本章範例使用Regex.isMatch方法,與前章範例差不多
不多做介紹!
來看一下Pattern
1. ^ 比對開始
2.([\w-\.]+)@ 比對一個或多個字符,包括字母數字和_與-最後比對@
3.(\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)  比對0~9至少1~3個 比對"."重複三次
4.| 或
5. (([\w-]+\.)+)) 一個或多個單詞與- 最後再比對.

6.  ( [a-zA-Z]{2,4} 比對大小寫a~z   2~4個  注意最前面(大誇號等等將進入ro判斷
7.| 又一個ro
8.[0-9]{1,3})  比對 0~9  一到三個
9.$");  比對結束

第1與第2 用於比對 @之前
第3與第4 用於@之後 形式可以這樣打 X7338681@123.123.123 或
第5 可以這樣打 X7338681@AB.AB.AB.AB.AB 並且無限多次
第5第6第7第8  也可以 單詞搭配 大小寫a~z 2~4個或數字1~3個
比如X733868@AB.CCCC
 或   X7338681@AB.123
這兩種形式


範例二十
驗證ip

範例如下
private void btn_Validate_Click(object sender, EventArgs e)
        {
            if (IPCheck(textBox1.Text))//驗證IP是否正確
            {
                MessageBox.Show("輸入IP正確");//彈出消息對話框
            }
            else { MessageBox.Show("輸入IP不正確"); }//彈出消息對話框
        }
        /// <summary>
        /// 驗證IP是否正確
        /// </summary>
        /// <param name="IP">IP地址字串</param>
        /// <returns>方法返回布林值</returns>
        public bool IPCheck(string IP)
        {
            string num = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)";//建立正規化運算式字串
            return Regex.IsMatch(IP,//使用正規化運算式判斷是否匹配
                ("^" + num + "\\." + num + "\\." + num + "\\." + num + "$"));
        }

一樣使用isMatch 不同的是 方法內中的 4個Pattern指向字串num
而num 是一個pattern 用來判斷是否0~255

1.  25[0-5]    判斷250~255
2.   |
3.  2[0-4]\\d    判斷200~249
4.   |
5.  [0-1]\\d{2}    判斷000~199
6.   |
7.   [1-9]?\\d)";    判斷10~99



範例二十一
驗證URL

範例如下
private void btn_Validate_Click(object sender, EventArgs e)
        {
            if (!IsUrl(textBox1.Text))//驗證網址格式是否正確
            { MessageBox.Show("網址格式不正確!!!"); }//彈出消息對話框
            else { MessageBox.Show("網址格式正確!!!!!"); }//彈出消息對話框
        }
        /// <summary>
        /// 驗證網址格式是否正確
        /// </summary>
        /// <param name="str_url">網址字串</param>
        /// <returns>方法返回布林值</returns>
        public bool IsUrl(string str_url)
        {
            return System.Text.RegularExpressions.Regex.IsMatch(str_url,//使用正規化運算式判斷是否匹配
@"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?");
        }

1.     http 比對http
2.    (s)?  比對有無s  0個或1個
3.     :   比對:
4.     //   比對//
5.    ([\w-]+\.)  比對單詞和-號   一個或多個 和.
6.    + 匹配第5項()內的子字串一次或多次
7.    [\w-]+  匹配單詞和-號 一次或多次
8.   (/[\w- ./?%&=]*)   匹配-./?%&符號 與 0個到多個字串
9.   ?   匹配第8項字串可以出現0或1次





本篇初學REGEX 介紹到這

下面將是 pattern 的符號引用 轉自維基百科

編號字元描述
1\將下一個字元標記為一個特殊字元、或一個原義字元、或一個向後參照、或一個八進制轉義符。例如,「n」匹配字元「n」。「\n」匹配一個換行符。序列「\\」匹配「\」而「\(」則匹配「(」。
2^匹配輸入字串的開始位置。如果設定了RegExp物件的Multiline屬性,^也匹配「\n」或「\r」之後的位置。
3$匹配輸入字串的結束位置。如果設定了RegExp物件的Multiline屬性,$也匹配「\n」或「\r」之前的位置。
4*匹配前面的子運算式零次或多次。例如:Gooo*gle 能匹配 Google、Goooooogle。* 等於 {0,}。
5+匹配前面的子運算式一次或多次。例如:Gooo+gle 能匹配 Gooogle、Goooooogle,但不能匹配 Google。+ 等於 {1,}
6?匹配前面的子運算式零次或一次。例如:Gooo?gle 只能匹配 Gooogle 和 Google。? 等於 {0,1}
7{n}n是一個非負整數。匹配確定的n次。例如:o{3} 能匹配 Gooogle 的 ooo,但不能匹配 Google。
8{n,}n是一個非負整數。至少匹配n次。
9{n,m}m和n均為非負整數,其中n<=m。最少匹配n次且最多匹配m次
10?當該字元緊跟在任何一個其他限制符(*,+,?,{n},{n,},{n,m})後面時,匹配範式是非貪婪的。非貪婪範式儘可能少的匹配所搜尋的字串,而預設的貪婪範式則儘可能多的匹配所搜尋的字串。
11.匹配除「\n」之外的任何單個字元。要匹配包括「\n」在內的任何字元,請使用像「[.\n]」的範式。
12(pattern)匹配pattern並獲取這一匹配。( ... ) 有群組的意思。例如:(ab) 能匹配 abc 中的 ab,但不能匹配 acc。
13(?:pattern)匹配pattern但不獲取匹配結果,也就是說這是一個非獲取匹配,不進行儲存供以後使用。例如:run(?:n|ning) 能匹配 running 整個字串,並且從此字串後繼續比對。
13(?=pattern)正向預查,在任何匹配pattern的字串開始處匹配尋找字串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。例如:Office(?=2003|2007|2010) 能匹配 Office2003 中的 Office,但不能匹配 Office2005 中的 Office,而從 Office 字串後繼續比對。
14(?!pattern)負向預查,在任何不匹配pattern的字串開始處匹配尋找字串。這是一個非獲取匹配,也就是說,該匹配不需要獲取供以後使用。例如:Office(?!2003|2007|2010) 能匹配 Office2005 中的 Office,但不能匹配 Office2010 中的 Office,而從 Office 字串後繼續比對。
15x|y匹配x或y。
16[xyz]字符集合。匹配所包含的任意一個字元。
17[^xyz]負值字符集合。匹配未包含的任意字元。
18[a-z]字元範圍。匹配指定範圍內的任意字元。
19[^a-z]負值字元範圍。匹配任何不在指定範圍內的任意字元。
20\b匹配一個單詞邊界,也就是指單詞和空格間的位置。

2013年12月5日 星期四

關於四捨五入的各種方法

如果我們要對整數 四捨五入可以使用
Math.Ceiling 或 Math.floor
如果數字7.5 Ceiling 後的結果是8
如果是 floor後的結果會是7

來看範例吧!

           double x = 5.5; //假如輸入5.5
            int s = 0; //宣告s 為輸出結果
            //下面使用Ceiling後 轉型為int
            s = Convert.ToInt16(Math.Ceiling(x));
            MessageBox.Show(s.ToString());
            s = Convert.ToInt16(Math.Floor(x));
            MessageBox.Show(s.ToString());
           
            //out 6
            //out 5


要注意的是
這個方法的行為會遵循 IEEE 標準 754,第 4 條。這種捨入有時稱為向正無限大方向捨入。換句話說,如果 a 是正值,則出現任何小數部分都會使 a 捨入至下一個最大整數。如果 a 是負值,則四捨五入運算會捨棄 a 的任何小數部分。這個方法的運算與 Floor(Double) 方法不同,其支援四捨五入成接近無限大的負數。

請看MSDN 的範例中的輸出
處理前 -0.12 
Cleiling後 = 0 
Floor = -1
注意的是-0.12是負號 Ceiling後結果並不會是 1
MSDN範例如下


double[] values = {7.03, 7.64, 0.12, -0.12, -7.1, -7.6};
Console.WriteLine("  Value          Ceiling          Floor\n");
foreach (double value in values)
   Console.WriteLine("{0,7} {1,16} {2,14}",
                     value, Math.Ceiling(value), Math.Floor(value));
// The example displays the following output to the console:
//         Value          Ceiling          Floor
//      
//          7.03                8              7
//          7.64                8              7
//          0.12                1              0
//         -0.12                0             -1
//          -7.1               -7             -8
//          -7.6               -7             -8


以上是單純的 進位

如果要處裡的數字是Double呢??
可以使用Round
將十進位的值捨入至最接近的整數值。
來看一下範例

            double[] values = { 2.125, 2.135, 2.145, 3.125, 3.135, 3.145 };
            foreach (double value in values)
                MessageBox.Show("原本是"+value.ToString()+"結果為"+Math.Round(value, 2));
            //  OutPut
            //  2.12
            //  2.13
            //  2.14
            //  3.12
            //  3.14
            //  3.14


Round 只說將十進位的值捨入至最接近的整數值。
並沒有說是 四捨五入 顯然這數值失真了

原因如下
由於將十進位值表示為浮點數,或者對浮點數值執行算術運算可能導致精確度喪失,因此在某些情況下,Round(Double) 方法可能無法將中點值四捨五入到最接近的偶數整數。


所以我們必須使用 Decimal整數
但是使用了Decimal 並不會是我們要得四捨五入
假如1.5 並不會變成2  而是要1.6才會 變成2
下列範例 將使用
Math.Round (double, MidpointRounding) 來證明!


using System;
public class Example
{
   public static void Main()
   {
      Console.WriteLine("{0,-10} {1,-10} {2,-10} {3,-15}", "Value", "Default",
                        "ToEven", "AwayFromZero");
      for (decimal value = 12.0m; value <= 13.0m; value += 0.1m)
         Console.WriteLine("{0,-10} {1,-10} {2,-10} {3,-15}",
                           value, Math.Round(value),
                           Math.Round(value, MidpointRounding.ToEven),
                           Math.Round(value, MidpointRounding.AwayFromZero));
   }
}
// The example displays the following output:
//       Value      Default    ToEven     AwayFromZero
//       12           12             12             12
//       12.1        12             12             12
//       12.2        12             12             12
//       12.3        12             12             12
//       12.4        12             12             12
//       12.5        12             12             13
//       12.6        13             13             13
//       12.7        13             13             13
//       12.8        13             13             13
//       12.9        13             13             13
//       13.0        13             13             13


這方法使用十進位 decimal
由for迴圈 12.0 累加到13.0 每次+0.1
並且 輸出 三種數值
Math.Round(value)
Math.Round(value, MidpointRounding.ToEven)
Math.Round(value, MidpointRounding.AwayFromZero))

讓讀者能更清楚知道 這之間的差異
Math.Round(Decimal)光是使用是不夠的
我們必須搭配 MidpointRounding.AwayFromZero 這個MODE

所以如果我們要完美得呈現四捨五入
我們必須使用這方法
Math.Round 方法 (Decimal, Int32, MidpointRounding)

下面將示範此方法

            Decimal[] values1 = { 2.125m, 2.135m, 2.145m, 3.125m, 3.135m, 3.145m };
            foreach (Decimal OK in values1)
            {
                MessageBox.Show("原本是" + OK.ToString() + "  結果為" +
                    Math.Round(OK, 2, MidpointRounding.AwayFromZero));
            }
            // OUTPUT
            // 原本是2.125 結果為2.13
            // 原本是2.135 結果為2.14
            // 原本是2.145 結果為2.15
            // 原本是3.125 結果為3.13
            // 原本是3.135 結果為3.14
            // 原本是3.145 結果為3.15




還有另外一種方法於書中範例中提到
當3.44444 + 0.00001
如何取小數點n位
呈現
3.5 
3.45
3.445
3.4445
下列範例為書中範例
可以解決這問題



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Round
{
    public partial class Frm_Main : Form
    {
        public Frm_Main()
        {
            InitializeComponent();
        }

        private void btn_Get_Click(object sender, EventArgs e)
        {
            double P_dbl_d1, P_dbl_d2;//定義兩個double類型變數
            if (double.TryParse(txt_add1.Text, out P_dbl_d1) &&//判斷輸入訊息是否正確
                double.TryParse(txt_add2.Text, out P_dbl_d2))
            {
                txt_add3.Text = //得到四捨五入後的值,傳值呼叫
                    Round(P_dbl_d1 + P_dbl_d2, cbox_select.SelectedIndex + 1).ToString();
            }
            else
            {
                MessageBox.Show(//提示錯誤訊息
                    "輸入數值不正確!", "提示!");
            }
        }

        /// <summary>
        /// 計算double值四捨五入的方法
        /// </summary>
        /// <param name="dbl">進行四捨五入的數值</param>
        /// <param name="i">保留的小數位</param>
        /// <returns>返回四捨五入後的double值</returns>
        internal double Round(double dbl, int i)
        {
            string P_str_dbl = dbl.ToString();//將double數值轉換為字串
            //將double數值小數位轉換為字串
            //注意! Split 傳回的是一個陣列
            //"."是分割字源[0]是小數點前[1]是小數點後
            string P_str_lower = P_str_dbl.Split('.')[1];
            int P_str_length = P_str_lower.Length;//計算double數值小數位長度
            dbl += GetValue(i, P_str_length);//開始進行四捨五入運算,傳直呼叫
            P_str_dbl = dbl.ToString();//將運算後的值轉換為字串
            if (P_str_dbl.Contains("."))//判斷是否存在小數位
            {
                string P_str_upper = //得到整數位字串
                    P_str_dbl.Split('.')[0];
                P_str_lower = P_str_dbl.Split('.')[1];//得到小數位字串
                if (P_str_lower.Length > i)//判斷數值位數是否大於保留小數位數
                {
                    P_str_lower = P_str_lower.Substring(//截取保留的小數位
                        0, i);//0起始位置為第一個小數,2是 娶幾個
                    return double.Parse(//返回double數值
                        P_str_upper + "." + P_str_lower);
                }
                else
                {
                    return double.Parse(P_str_dbl);//如數值位數小於保留小數位數則直接返回
                }
            }
            else
            {
                return double.Parse(P_str_dbl);//如果沒有小數位則直接返回值
            }
        }

        /// <summary>
        /// 得到小數數值的方法
        /// </summary>
        /// <param name="int_null">四捨五入保留的位數</param>
        /// <param name="length">四捨五入丟失的位數</param>
        /// <returns>返回小數值用於四捨五入計算</returns>
        internal double GetValue(int int_null, int length)
        {
            string P_str_dbl = "0.";//定義字串變數並賦值
            for (int i = 0; i < length; i++)//使用for循環新增小數位
            {
                if (i > int_null - 1)
                {
                    P_str_dbl += "5";//向小數的四捨五入部分加5
                }
                else
                {
                    P_str_dbl += "0";//向小數的保留部分加0
                }
            }
            return double.Parse(P_str_dbl);//返回小數數值 ,轉型為double
        }

        private void Frm_Main_Load(object sender, EventArgs e)
        {
            cbox_select.SelectedIndex = 0;//cbox_select控制元件默認選擇第一項
        }

    }
}