Regular Expression trong C#

Regular expression (cụm từ thông dụng) là một pattern (mẫu) mà có thể được so khớp với một văn bản đầu vào. .Net Framework cung cấp một công cụ regular expression cho phép so khớp như vậy. Trong C#, một pattern gồm một hoặc nhiều hằng ký tự, toán tử, hoặc construct.

Có nhiều loại ký tự, toán tử và construct khác nhau giúp bạn định nghĩa Regular Expression trong C#:

  • Character escape
  • Lớp Character
  • Anchor
  • Grouping construct
  • Quantifier
  • Backreference construct
  • Alternation construct
  • Substitution
  • Miscellaneous constructs

Construct để định nghĩa Regular Expression trong C#

  • Character escape trong C#
  • Anchor trong C#
  • Grouping construct trong C#
  • Lớp Character trong C#
  • Quantifier trong C#
  • Backreference construct trong C#
  • Alternation construct trong C#
  • Substitution trong C#
  • Construct trong C#
  • Lớp Regex trong C#

Character escape trong C#

Về cơ bản, Escape Character trong C# là những ký tự đặc biệt. Ký tự dấu gạch chéo ngược (\) trong một Regular Expression chỉ rằng ký tự theo sau nó: hoặc là một ký tự đặc biệt hoặc nên được thông dịch theo từng ký tự.

Dưới đây là các Escape Character trong C#:

Escape character Mô tả Pattern So khớp
\a So khớp một ký tự bell, \u0007 \a “\u0007” trong “Warning!” + ‘\u0007’
\b Trong một lớp ký tự, so khớp một backspace, \u0008 [\b]{3,} “\b\b\b\b” trong “\b\b\b\b”
\t So khớp một tab, \u0009 (\w+)\t “Name\t”, “Addr\t” trong “Name\tAddr\t”
\r So khớp một carriage return, \u000D. (\r là không tương đương với ký tự newline (dòng mới), \n) \r\n(\w+) “\r\nHello” trong “\r\Hello\nWorld.”
\v So khớp một tab dọc, \u000B [\v]{2,} “\v\v\v” trong “\v\v\v”
\f So khớp một form feed, \u000C [\f]{2,} “\f\f\f” trong “\f\f\f”
\n So khớp một newline (dòng mới), \u000A \r\n(\w+) “\r\nHello” trong “\r\Hello\nWorld.”
\e So khớp một escape, \u001B \e “\x001B” trong “\x001B”
\nnn Sử dụng biểu diễn hệ cơ số 8 để xác định một ký tự (nnn gồm 3 chữ số) \w\040\w “a b”, “c d” trong “a bc d”
\x nn Sử dụng biểu diễn hệ cơ số 16 để xác định một ký tự (nn gồm 2 chữ số) \w\x20\w “a b”, “c d” trong “a bc d”
\c X\c x So khớp ký tự điều khiển ASCII mà được xác định bởi X hoặc x, với X hoặc x là chữ cái của ký tự điều khiển \cC “\x0003” trong “\x0003” (Ctrl-C)
\u nnnn So khớp môt ký tự Unicode bởi sử dụng biểu diễn thập lục phân (gồm 4 chữ số, như được biểu diễn bởi nnnn) \w\u0020\w “a b”, “c d” trong “a bc d”
\ Khi được theo sau bởi một ký tự mà không được nhận ra như là một Escape Character, thì so khớp ký tự đó \d+[\+-x\*]\d+\d+[\+-x\*\d+ “2+2” and “3*9” trong “(2+2) * 3*9”

Anchor trong C#

Anchor cho phép một match để thực hiện thành công hoặc thất bại phụ thuộc vào vị trí hiện tại trong chuỗi. Dưới đây là các anchor trong C#:

Assertion Mô tả Pattern So khớp
^ Tác vụ so khớp phải bắt đầu tại phần đầu của chuỗi hoặc dòng. ^\d{3} “567” trong “567-777-“
$ So khớp phải bắt đầu tại phần cuối của chuỗi hoặc trước \n tại phần cuối của dòng hoặc chuỗi. -\d{4}$ “-2012” trong “8-12-2012”
\A So khớp phải bắt đầu tại phần đầu của chuỗi. \A\w{3} “Code” trong “Code-007-“
\Z So khớp phải bắt đầu tại phần cuối của chuỗi hoặc trước \n tại phần cuối của chuỗi. -\d{3}\Z “-007” trong “Bond-901-007”
\z So khớp phải bắt đầu tại phần cuối của chuỗi. -\d{3}\z “-333” trong “-901-333”
\G So khớp phải bắt đầu tại điểm mà ở đó so khớp trước kết thúc. \\G\(\d\) “(1)”, “(3)”, “(5)” trong “(1)(3)(5)[7](9)”
\b So khớp phải bắt đầu trên một giới hạn giữa một \w (chữ-số) và một \W(không là chữ-số). \w “R”, “o”, “m” và “1” trong “Room#1”
\B So khớp phải không bắt đầu trên một giới hạn \b \Bend\w*\b “ends”, “ender” trong “end sends endure lender”

Grouping construct trong C#

Grouping Construct trong C# mô tả các sub-expression của một Regular Expression và bắt các chuỗi phụ trong một input string. Bảng dưới đây liệt kê các Grouping Construct trong C#:

Grouping construct Mô tả Pattern So khớp
( subexpression ) Bắt subexpression đã so khớp và gán cho nó một số thứ tự dựa trên cơ sở 0. (\w)\1 “ee” trong “deep”
(?< name >subexpression) Bắt subexpression đã so khớp bên trong một nhóm đã được đặt tên. (?< double>\w)\k< double> “ee” trong “deep”
(?< name1 -name2 >subexpression) Định nghĩa một sự định nghĩa nhóm cân bằng. (((?’Open’\()[^\(\)]*)+((?’Close-Open’\))[^\(\)]*)+)*(?(Open)(?!))$ “((1-3)*(3-1))” trong “3+2^((1-3)*(3-1))”
(?: subexpression) Định nghĩa một noncapturing group. Write(?:Line)? “WriteLine” trong “Console.WriteLine()”
(?imnsx-imnsx:subexpression) Áp dụng hoặc vô hiệu hóa các tùy chọn đã xác định bên trong subexpression. A\d{2}(?i:\w+)\b “A12xl”, “A12XL” trong “A12xl A12XL a12xl”
(?= subexpression) \w+(?=\.) “is”, “ran”, và “out” trong “He is. The dog ran. The sun is out.”
(?! subexpression) \b(?!un)\w+\b “sure”, “used” trong “unsure sure unity used”
(?< =subexpression) (?< =19)\d{2}\b “51”, “03” trong “1851 1999 1950 1905 2003”
(?< ! subexpression) (?< !19)\d{2}\b “ends”, “ender” trong “end sends endure lender”
(?> subexpression) [13579](?>A+B+) “1ABB”, “3ABB”, và “5AB” trong “1ABB 3ABBC 5AB 5AC”

Lớp Character trong C#

Một lớp Character trong C# so khớp bất kỳ ký tự nào trong một tập hợp các ký tự. Dưới đây là các lớp Character trong C#:

Lớp Character Mô tả Pattern So khớp
[character_group] So khớp bất kỳ ký tự đơn nào trong character_group. Theo mặc định, tác vụ so khớp là phân biệt kiểu chữ (case-sensitive) [mn] “m” trong “mat” “m”, “n” trong “moon”
[^character_group] Phủ định: So khớp bất kỳ ký tự nào không ở trong character_group. Theo mặc định, các ký tự trong character_group là case-sensitive [^aei] “v”, “l” trong “avail”
[ first – last ] Dãy ký tự: So khớp bất kỳ ký tự nào trong dãy ký tự từ first tới last [b-d] [b-d]irds Birds Cirds Dirds
. Wildcard: So khớp bất kỳ ký tự đơn nào ngoại trừ \n a.e “ave” trong “have” “ate” trong “mate”
\p{ name } So khớp bất kỳ ký tự đơn nào trong kiểu Unicode chung hoặc khối được xác định bởi name \p{Lu} “C”, “L” trong “City Lights”
\P{ name } So khớp bất kỳ ký tự đơn nào mà không trong kiểu Unicode chung hoặc khối được xác định bởi name \P{Lu} “i”, “t”, “y” trong “City”
\w So khớp bất kỳ ký tự từ (word) nào \w “R”, “o”, “m” và “1” trong “Room#1”
\W So khớp bất kỳ ký tự không phải từ (non-word) nào \W “#” trong “Room#1”
\s So khớp bất kỳ ký tự whitespace \w\s “D ” trong “ID A1.3”
\S So khớp bất kỳ ký tự non-whitespace \s\S ” _” trong “int __ctr”
\d So khớp bất kỳ chữ số thập phân nào \d “4” trong “4 = IV”
\D So khớp bất kỳ ký tự nào khác ngoài một chữ số thập phân \D ” “, “=”, ” “, “I”, “V” trong “4 = IV”

Quantifier trong C#

Quantifier trong C# xác định có bao nhiêu instance (sự thể hiện) của phần tử trước (mà có thể là một ký tự, một nhóm, hoặc một lớp Character) phải là có mặt trong input string để một match xảy ra.

Quantifier Mô tả Pattern So khớp
* So khớp với phần tử trước 0 hoặc nhiều lần \d*\.\d “.0”, “19.9”, “219.9”
+ So khớp với phần tử trước 1 hoặc nhiều lần “be+” “bee” in “been”, “be” trong “bent”
? So khớp với phần tử trước 0 hoặc 1 lần “rai?n” “ran”, “rain”
{ n } So khớp với phần tử trước n lần “,\d{3}” “,043” in “1,043.6”, “,876”, “,543”, và “,210” trong “9,876,543,210”
{ n ,} So khớp với phần tử trước ít nhất n lần “\d{2,}” “166”, “29”, “1930”
{ n , m } So khớp với phần tử trước ít nhất n lần, nhưng không lớn hơn m lần “\d{3,5}” “166”, “17668” “19302” trong “193024”
*? So khớp với phần tử trước 0 hoặc nhiều lần, nhưng với số lần ít nhất có thể \d*?\.\d “.0”, “19.9”, “219.9”
+? So khớp với phần tử trước 1 hoặc nhiều lần, nhưng với số lần ít nhất có thể “be+?” “be” trong “been”, “be” trong “bent”
?? So khớp với phần tử trước 0 hoặc 1 lần, nhưng với số lần ít nhất có thể “rai??n” “ran”, “rain”
{ n }? So khớp với phần tử trước n lần “,\d{3}?” “,043” trong “1,043.6”, “,876”, “,543”, và “,210” trong “9,876,543,210”
{ n ,}? So khớp với phần tử trước ít nhất n lần, nhưng với số lần ít nhất có thể “\d{2,}?” “166”, “29”, “1930”
{ n , m }? So khớp với phần tử trước với số lần trong khoảng n và m, nhưng với số lần ít nhất có thể “\d{3,5}?” “166”, “17668” “193”, “024” trong “193024”

Backreference construct trong C#

Backreference construct trong C# cho phép một sub-expression đã được so khớp trước đó được xác định tiếp theo trong cùng Regular Expression đó.

Đây là danh sách các construct này trong C#:

Backreference construct Mô tả Pattern So khớp
\ number Backreference. So khớp với giá trị của subexpression đã được đánh số. (\w)\1 “ee” trong “seek”
\k< name > Backreference đã được đặt tên. So khớp với giá trị của expression đã được đặt tên. (?< char>\w)\k< char> “ee” trong “seek”

Alternation construct trong C#

Alternation construct trong C# sửa đổi một Regular Expression để kích hoạt có/không tác vụ so khớp. Bảng dưới đây là danh sách các Alternation construct trong C#:

Alternation construct Miêu tả Pattern So khớp
| So khớp với bất kỳ một phần tử được phân biệt riêng rẽ bởi ký tự (|) th(e|is|at) “the”, “this” trong “this is the day. “
(?( expression )yes | no ) So khớp với yes nếu expression là khớp; nếu không thì, so khớp phần notùy ý. Expression được thông dịch như là một zero-width assertion (?(A)A\d{2}\b|\b\d{3}\b) “A10”, “910” trong “A10 C103 910”
(?( name )yes | no ) So khớp với yes nếu name được bắt có một match; nếu không thì, so khớp với notùy ý (?< quoted>”)?(?(quoted).+?”|\S+\s) Dogs.jpg, “Yiska playing.jpg” trong “Dogs.jpg “Yiska playing.jpg””

Substitution trong C#

Substitution trong C# được sử dụng trong các pattern thay thế. Bảng dưới liệt kê các Substitution trong C#:

Ký tự Miêu tả Pattern Pattern thay thế Input string Chuỗi kết quả
$number Thay thế substring đã được so khớp bởi number. \b(\w+)(\s)(\w+)\b $3$2$1 “one two” “two one”
${name} Thay thế substring đã được so khớp bởi groupname. \b(?< word1>\w+)(\s)(?< word2>\w+)\b “one two” “two one”
$$ Thay thế một hằng “$”. \b(\d+)\s?USD $$$1 “103 USD” “$103”
$& Thay thế một bản sao của cả match. ($*(\d*(\.+\d+)?){1}) **$& “$1.30” “**$1.30**”
$` Thay thế tất cả text của input string ở trước một match. B+ $` “AABBCC” “AAAACC”
$’ Thay thế tất cả text của input string ở sau một match. B+ $’ “AABBCC” “AACCCC”
$+ Thay thế nhóm cuối cùng mà đã được bắt. B+(C+) $+ “AABBCCDD” AACCDD
$_ Thay thế cả input string. B+ $_ “AABBCC” “AAAABBCCCC”

Construct trong C#

Bảng dưới liệt kê các construct hỗn hợp trong C#:

Construct Định nghĩa Ví dụ
(?imnsx-imnsx) Thiết lập hoặc vô hiệu hóa các tùy chọn như phân biệt kiểu chữ trong phần giữa một pattern. \bA(?i)b\w+\b so khớp “ABA”, “Able” trong “ABA Able Act”
(?#comment) Inline comment. Comment kết thúc tại dấu ngoăc đơn đóng đầu tiên. \bA(?#So khop cac tu bat đau voi A)\w+\b
[den cuoi dong] X-mode comment. Comment bắt đầu từ # và tiếp tục tới phần cuối dòng. (?x)\bA\w+\b#So khop cac tu bat đau voi A

Lớp Regex trong C#

Lớp Regex trong C# được sử dụng để biểu diễn một Regular Expression. Nó có các phương thức được sử dụng phổ biến sau:

STT Phương thức
1 public bool IsMatch(string input)Chỉ rằng có hay không Regular Expression đã cho trong Regex constructor này tìm thấy một match trong chuỗi đầu vào đã xác định.
2 public bool IsMatch(string input, int startat)Chỉ rằng có hay không Regular Expression đã cho trong Regex constructor này tìm thấy một match trong chuỗi đầu vào đã xác định, bắt đầu tại vị trí startat đã cho trong chuỗi.
3 public static bool IsMatch(string input, string pattern)Chỉ rằng có hay không Regular Expression đã cho tìm thấy một match trong chuỗi đầu vào đã xác định.
4 public MatchCollection Matches(string input)Tìm kiếm chuỗi đầu vào đã xác định về tất cả sự xuất hiện của một Regular Expression.
5 public string Replace(string input, string replacement)Trong một chuỗi đầu vào đã xác định, thay thế tất cả chuỗi mà so khớp với một Regular Expression pattern với một chuỗi thay thế đã cho.
6 public string[] Split(string input)Chia một chuỗi đầu vào thành một mảng các chuỗi phụ tại vị trí được định nghĩa bởi một Regular Expression pattern đã xác định trong Regex constructor.

Để có danh sách đầy đủ các phương thức và thuộc tính, bạn vui lòng đọc Microsoft Documentation về C#.

Ví dụ 1: So khớp các từ bắt đầu với S

using System;
using System.Text.RegularExpressions;

namespace QTMCSharp {
   class Program {
      private static void showMatch(string text, string expr) {
         Console.WriteLine("Biểu thức: " + expr);
         MatchCollection mc = Regex.Matches(text, expr);
         
         foreach (Match m in mc) {
            Console.WriteLine(m);
         }
      }
      static void Main(string[] args) {
         string str = "Sao hôm nay Sáng quá!";
         
         Console.WriteLine("So khớp các từ bắt đầu với 'S': ");
         showMatch(str, @"\bS\S*");
         Console.ReadKey();
      }
   }
}

Biên dịch và chạy chương trình C# trên bạn sẽ nhận được kết quả như sau:

So khp các t bt đầu vi 'S': 
Biu thc: \bS\S*
Sao
Sáng

Ví dụ 2: So khớp các từ bắt đầu với c và kết thúc với m

using System;
using System.Text.RegularExpressions;

namespace QTMCSharp {
   class Program {
      private static void showMatch(string text, string expr) {
         Console.WriteLine("Biểu thức: " + expr);
         MatchCollection a = Regex.Matches(text, expr);
         
         foreach (Match b in a) {
            Console.WriteLine(b);
         }
      }
      static void Main(string[] args) {
         string str = "Quản trị mạng chấm com";

         Console.WriteLine("So khớp từ bắt đầu với 'c' và kết thúc với 'm':");
         showMatch(str, @"\bc\S*m\b");
         Console.ReadKey();
      }
   }
}

Biên dịch và chạy chương trình C# trên sẽ cho kết quả đầu ra như sau:

So khp t bt đầu vi 'c' và kết thúc vi 'm':
Biu thc: \bc\S*m\b
chm
com

Ví dụ 3: Thay thế khoảng trống (white space):

using System;
using System.Text.RegularExpressions;

namespace RegExApplication {
   class Program {
      static void Main(string[] args) {
         string input = "  QTM    chào    bạn!   ";
         string pattern = "\\s+";
         string replacement = " ";
         
         Regex rgx = new Regex(pattern);
         string result = rgx.Replace(input, replacement);

         Console.WriteLine("Chuỗi ban đầu: {0}", input);
         Console.WriteLine("Chuỗi đã thay thế khoảng trống: {0}", result);    
         Console.ReadKey();
      }
   }
}

Biên dịch và chạy chương trình C# trên sẽ cho kết quả sau:

Chui ban đầu:  QTM    chào    bn!
Chui đã thay thế khong trng: QTM chào bn!