C# Regular Expression
本文章列出只在 C# 作用的相關進階項目
一、Character Classes
1、\p{name}:表示一個 Unicode Property 的字元
using System;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string str = "abC";
string pattern = @"\p{Lu}";
Match m = Regex.Match(str, pattern);
Console.WriteLine(m.Value);
}
}
}
其結果為
說明:
Unicode Property 的名稱為 Lu 時,代表大寫字元;
Unicode Property 的名稱為 Ll 時,代表小寫字元。
2、\P{name}:表示一個非 Unicode Property 的字元
二、Anchors
1、「\A」:作用相等於「^」。
2、「\z」:作用相等於「$」。
using System;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string str = "12345\n345";
string pattern = @"345\z";
string result = Regex.Replace(str, pattern, "*");
Console.WriteLine(result);
}
}
}
其結果為
3、「\Z」:作用相等於「$」,另外一點,當最後面有「\n」字元時,也是符合的。
using System;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string str = "12345\n345\n";
string pattern = @"345\Z";
string result = Regex.Replace(str, pattern, "*");
Console.WriteLine(result);
}
}
}
其結果為
4、「\G」:於開頭一開始就符合條件,直到被「不符合條件」中斷為止。
using System;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string str = "123b456";
string pattern = @"\G\d";
string result = Regex.Replace(str, pattern, "*");
Console.WriteLine(result);
}
}
}
其結果為
三、Greedy and Lazy Quantifiers
1、Greedy Quantifiers
Quantifiers 有下列六項,預設為 greedy,
也就是說其 Regex engine 在比對時會盡力找出所有符合條件者,
並回傳最後一位符合條件者。
a、「*」
b、「+」
c、「?」
d、「{n}」
e、「{n,}」
f、「{n,m}」
using System;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string pattern = @"\b.*([0-9]{4})\b";
string str = @"1112223333 3992991999";
foreach (Match match in Regex.Matches(str, pattern))
Console.WriteLine("Account ending in ******{0}.", match.Groups[1].Value);
}
}
}
其結果為
2、Lazy Quantifiers
而 non-greedy Quantifiers (Lazy Quantifiers),也有六項,
跟 Greedy Quantifiers 差別只是於其後再加上一個「?」。
使用 Lazy Quantifiers 時,Regex engine 不會積極找出所有符合條件者,
只要一找到符合條件者即立刻停止搜尋。
a、「*?」
b、「+?」
c、「??」
d、「{n}?」
e、「{n,}?」
f、「{n,m}?」
using System;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string pattern = @"\b.*?([0-9]{4})\b";
string str = @"1112223333 3992991999";
foreach (Match match in Regex.Matches(str, pattern))
Console.WriteLine("Account ending in ******{0}.", match.Groups[1].Value);
}
}
}
其結果為
四、Alternation Constructs
1、「x|y」:x、y 為任一字元條件,其意思為有成功比對到 x 或 y,皆符合。
using System;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string pattern = @"(abc|def)";
string str = @"abc-def";
string result = Regex.Replace(str, pattern, "*");
Console.WriteLine(result);
}
}
}
其結果為
2、Conditional matching with an expression
syntax:(?(condition)true|false)
using System;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string pattern = @"\b(?([g])[g]\w+|[a]\w+)\b";
string str = @"facebook google apple microsoft";
foreach (Match match in Regex.Matches(str, pattern))
{
Console.WriteLine("{0} at position {1}", match.Value, match.Index);
}
}
}
}
其結果為
說明:
這就像是 if else 條件式,整個 Conditional matching expression 為
(?([g])[g]\w+|[a]\w+)
condition 為 [g],true 的話則取 [g]\w+,false 的話則取 [a]\w+。
condition 只用於條件判斷不參與 pattern 比對。
3、Conditional matching based on a valid captured group
syntax:(?<conditionName>condition)?(?(conditionName)true|false)
using System;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string pattern = @"\b(?<myName>[g])?(?(myName)\w+|[a]\w+)\b";
string str = @"facebook google apple microsoft";
foreach (Match match in Regex.Matches(str, pattern))
{
Console.WriteLine("{0} at position {1}", match.Value, match.Index);
}
}
}
}
其結果為
說明:
整個 Conditional matching expression 為 (?<myName>[g])?(?(myName)\w+|[a]\w+)
true 的話則取 (?<myName>[g])?\w+
false 的話則取 (?<myName>[g])?[a]\w+
五、comment
syntax:(?#comment)
using System;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string pattern = @"(?#找尋古歌)google(?#找尋古歌)";
string str = @"facebook google apple microsoft";
string result = Regex.Replace(str, pattern, "*");
Console.WriteLine(result);
}
}
}
其結果為
說明:
其範例主要演示為可在 pattern 裡面下註解,只要使用 (?#comment) 語法。
六、特殊字元
這些都是特殊字元「. ^ $ * + ? = { } [ ] \ | ( )」,
在 regular expression pattern 裡,如果只想把他單純以字元看待,
則需加上跳脫字元「\」。
例如:「\.」、「\+」、「\=」。
using System;
using System.Text.RegularExpressions;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string input = "^";
string pattern = "\\^";
string result = Regex.Replace(input, pattern, "*");
Console.WriteLine(result);
}
}
}
其結果為
七、撰寫技巧
1、在寫 regular expression 時,在 pattern 裡使用「.*」都要小心,
最好於其前後都要有特徵字元或字串可判斷,否則很容易一下子就把全部內容都篩出來了。
2、以上情形可考慮使用 Lazy Quantifiers 來處理可能會較合適。
3、regular expression 被用於 parse 時,預設是由左往右解析。
4、在 windows 系統,換行是由 \r\n 組成,也就是 Carriage Return 與 Line feed。
八、速查表
參考資料: