2016/02/25

[Regex][C#] Pattern 比對的順序

假設要拆解 (A,B),C,(D,E,F),G 這樣的字串, 成為如下的結果:
(A,B)
C
(D,E,F)
G

第一個想到的會是用逗號(,)做分隔符號試試, 但得到的結果如下:
(A
B)
C
(D
E
F)
G



換用 match pattern 的方式來思考, 有以下兩種 patterns 是我們要的:
  1. 被小括號框住的視為一個 pattern: \(.*?\)  
  2. 逗號之間的字元視為一個 pattern: [^,]+
以 C# 的程式實作, 大致如下:
string s = "(A,B),C,(D,E,F),G";
MatchCollection matchs = Regex.Matches(s, @"\(.*?\)|[^,]+", RegexOptions.IgnoreCase);
foreach (Match m in matchs)
{
  Console.WriteLine(m.Value);
}
輸出的結果如下:
(A,B)
C
(D,E,F)
G
另外, 文章標題提到比對的順序, 以下我們將兩個比對的順序調換看看有什麼影響:
string s = "(A,B),C,(D,E,F),G";
MatchCollection matchs = Regex.Matches(s, @"[^,]+|\(.*?\)", RegexOptions.IgnoreCase);
foreach (Match m in matchs)
{
  Console.WriteLine(m.Value);
}
會發現結果如下:
(A
B)
C
(D
E
F)
G
由此可知, 比對順序的不同, 會連帶影響 match 的結果.
PS. 這樣的 patterns 有些許沒滿足的地方, 例如: 巢狀的括號, 逗號之間是空字元的情況等.

如果要用雙引號(")做類似小括號的事, 可參考如下:
".*?"|[^,]+
如果要用中括號({ })做類似小括號的事, 可參考如下:
\[.*?\]|[^,]+

沒有留言: