Biểu thức chính tắc (regular expression)
Giới thiệu biểu thức chính tắc
Một biểu thức chính tắc (regular expression) là một mẫu có thể so khớp hay kiểm tra tính phù hợp của một văn bản đầu vào. Một mẫu biểu thức chính tắc bao gồm một hoặc nhiều ký tự chữ cái, toán tử hoặc cấu trúc.
Xây dựng định nghĩa cho biểu thức chính tắc
Có nhiều loại ký tự, toán tử và cách thức xây dựng để định nghĩa biểu thức chính tắc. Sau đây là một số cách thức xây dựng thông dụng:
- Character escape
- Character class
- Anchor
- Grouping construct
- Quantifier
Character escape
Về cơ bản, character escape 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ự mà 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ự.
Bảng dưới liệt kê các character escape trong C#:
ESCAPE CHARACTER | MÔ TẢ | MẪU | 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" |
Character class
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ự. Bảng sau miêu tả các lớp Character trong C#:
CHARACTER CLASS | MÔ TẢ | MẪU | 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" |
Anchor
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. Bảng dưới đây liệt kê các anchor trong C#:
ANCHOR | MÔ TẢ | MẪU | 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
Grouping construct trong C# mô tả các sub-expression của một biểu thức chính tắc và bắt các chuỗi phụ trong một chuỗi đầu vào. Bảng sau liệt kê các grouping construct trong C#:
GROUPING CONSTRUCT | MÔ TẢ | MẪU | 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" |
Quantifier
Quantifier trong C# xác định có bao nhiêu thể hiện của phần tử (có thể là một ký tự, một nhóm, hoặc một character class) có mặt trong xâu đầu vào cho một phù hợp với so khớp cụ thể.
QUANTIFIER | MÔ TẢ | MẪU | 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" |
Lớp Regex
Lớp Regex được sử dụng để biểu diễn một biểu thức hợp lệ. Sau đây là một số phương thức thông dụng của lớp Regex:
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 |
Ví dụ về sử dụng biểu thức chính tắc
Ví dụ CheckStartStringREDemo sau đây sẽ kiểm tra xem chuỗi đầu vào có bắt đầu bởi chữ cái 'S':
Ví dụ CheckEndStringREDemo sau đây sẽ kiểm tra từ nhập vào có bắt đầu bởi chữ cái 'm' và kết thúc bởi chữ cái 'e':
Ví dụ ReplaceSpacesREDemo sau đây sẽ cho phép thay thế các ký tự trắng trong một xâu: