有些解答看起來很複雜, 實際上只要一個一個 pattern 拆解, 就不難發現道理其實很簡單.
以下的例子將視情況進行補充:
- 抓取雙引號 ("..."), 大括號 ({...}) 等被特殊符號框住的字串:
以雙引號為例, 參考以下的 Code: (不抓取空字串)string strTest = "<a href=\"http://www.w3schools.com/html/default.asp\" class=\"cLink\">HTML</a><br/>"; //這是錯誤的寫法 MatchCollection matches = Regex.Matches(strTest, "\".+\"", RegexOptions.IgnoreCase); foreach (Match match in matches) { Console.WriteLine(match.Value); //結果:"http://www.w3schools.com/html/default.asp" class="cLink" } //這是正確的寫法 matches = Regex.Matches(strTest, "\"[^\"]+\"", RegexOptions.IgnoreCase); foreach (Match match in matches) { Console.WriteLine(match.Value); //結果:"http://www.w3schools.com/html/default.asp" // "cLink" } //這也是正確的寫法 matches = Regex.Matches(strTest, "\".+?\"", RegexOptions.IgnoreCase); foreach (Match match in matches) { Console.WriteLine(match.Value); //結果:"http://www.w3schools.com/html/default.asp" // "cLink" }
上述的例子說明如下:
Step1: 設定起始的符號, 也就是給一個雙引號.
Step2: 再來是設定結束的符號, 這部分一樣是給一個雙引號.
Step3: 在中括號的開頭填入一個 '^', 表示要排除掉中括號裡所列的字元, 這邊要排除的字元就放結束符號, 表示除了結束字元外的字元我們都要吃.
在 '^' 符號後面接一個 Step2 的結束符號並在中括號外面給一個 '+', 表示開始與結束符號中至少要有一個字元, 若要允許空字串就給 '*'.
最後一種寫法可參考: http://www.regular-expressions.info/reference.html 的 lazy 說明.
同樣的道理, 如果要取大括號裡的字串, 表示式就是: "{[^}]+}" 或 '{.+?}'. - 承1. 如果不想要 Match 後的字串包含開始與結束字元, 就可以使用 Regular Expression 中的 Group 概念, 或是用字串的 Trim, 例如: match.Value.Trim('\"') .
例如以下的 Code:string strTest = "<a href=\"http://www.w3schools.com/html/default.asp\" " + "class=\"cLink\">HTML</a><br/>"; //將雙引號中的字串放進一個名為item的Group中 MatchCollection matches = Regex.Matches(strTest, "\"(?<item>[^\"]+)\"", RegexOptions.IgnoreCase); foreach (Match match in matches) { Console.WriteLine(match.Groups["item"].Value); //結果:http://www.w3schools.com/html/default.asp // cLink }
蠻簡單的做法, 只要將起始與結束符號中的 Pattern 放在 (?<item>) 裡, 然後用 match.Groups["item"].Value 去取值就可以.
不過初步還是先用 match.Value 去確認有抓對, 再去思考要怎麼拆解成 Group. - 在字串的取代方面, string.Replace(string oldValue, string newValue) 是一對一的取代, 如果要多對多或多對一的取代, 可以用 Regex.Replace.
例如, 我們想把字串中所有的標籤 (<...>) 刪除掉, 可以用以下的 Code:string strTest = "<a href=\"http://www.w3schools.com/html/default.asp\" " +"class=\"cLink\">HTML</a><br/>"; //利用"<[^>]+>", 找出所有的<...> Console.WriteLine(Regex.Replace(strTest, "<[^>]+>", string.Empty)); //結果:HTML
看起來比 string.Replace 好用, 也比較彈性. 不過還是要注意要 Replace 掉的 Pattern 要寫對. - Regex.Replace 還有一個用法, 就是透過 delegate 的方式做取代的後處理.
這一般用在比對的 Pattern 寫得不是很精準的時候用, 透過後處理的方式決定要不要進行取代.
例如, 如果我們想移除所有的 HTML 標籤, 但又想留住 <br> 這個標籤, 就可以參考以下的 Code:string strTest = "<a href=\"http://www.w3schools.com/html/default.asp\" " + "class=\"cLink\">HTML</a><br/>"; string strResult = Regex.Replace(strTest, "<[^>]+>", delegate(Match m) { //如果查到的字串是以"<br"為開頭, 就不取代, 而回傳原本比對到的字串 if (m.Value.StartsWith("<br", StringComparison.OrdinalIgnoreCase)) { return m.Value; } else { //除了<br>以外的字串,都換成空字串 return string.Empty; } } ); Console.WriteLine(strResult); //結果:HTML<br/>
這樣的寫法, 還可以應用在許多地方. 例如進行關鍵字的 highlight, 或是移除掉一些敏感字眼. - (2009/06/26補充) 有時候, 礙於畫面好看或是資料的縮排, 會對一個很長的字串做指定長度的斷行.
舉例來說, 有一長串文字, 我們希望每 10 個字換一行. 有人會撰寫如下的程式去處理:string strSource = "Windows 7已確定十月二十二日上市,為避免上市前電腦買氣遲滯," + "微軟提供Vista到Windows 7免費升級方案。"; string strResult = string.Empty; for (int i = 0; i < strSource.Length; i += 10) { strResult += strSource.Substring(i, strSource.Length < (i + 10) ? strSource.Length - i : 10) + Environment.NewLine; } Console.WriteLine(strResult);
(2009/09/16修改) 如上的作業也可以用 Regex.Replace() 完成:string strSource = "Windows 7已確定十月二十二日上市,為避免上市前電腦買氣遲滯," + "微軟提供Vista到Windows 7免費升級方案。"; Console.WriteLine(Regex.Replace(strSource, "(?!.{10}$).{10}", delegate(Match m) { return m.Value + Environment.NewLine; })); //或是用到群組概念 Console.WriteLine(Regex.Replace(strSource, "(?!.{10}$)(.{10})", "$1" + Environment.NewLine));
只要把 10 這個數字換成其它數字, 就能依指定長度斷行. 不過上例中文字也算長度 1, 所以若是中英夾雜的字串, 斷行後的長度看起來還是會不一致. (要注意)
不過如果懂得用, 是還蠻方便的.
1 則留言:
寫得不錯~~
張貼留言