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。

 

八、速查表

 

 

參考資料:

Regex Class

Regular Expressions

Unicode Property

[入門][Regex] Regular Expression 詳論

[Regex] 進階群組建構

[Regex] 值得注意的 Regular Expression 樣式的潛在風險