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