Regular Expression trong C#
Khóa học lập trình C# căn bản

Danh sách bài học
Regular Expression trong C#
Nội dung bài viết Học nhanh
- Dẫn nhập
- Nội dung
- Các ký hiệu của Regular Expression
- Pattern .
- Pattern \d
- Pattern \D
- Pattern \s
- Pattern \S
- Pattern \w
- Pattern \W
- Pattern ^
- Pattern $
- Pattern \A
- Pattern \z
- Pattern |
- Pattern [abc]
- Pattern [a-z]
- Pattern [^abc]
- Pattern ()
- Pattern ?
- Pattern *
- Pattern +
- Pattern {n}
- Pattern {n,}
- Pattern {m,n}
- Một số lớp hỗ trợ trong Regular Expression
- Tải phần mềm
- Kết luận
- Tải xuống
- Thảo luận
Dẫn nhập
Regular Expression hay tiếng Việt được gọi là Biểu thức chính quy, là một cấu trúc rất mạnh để mô tả một chuỗi theo cách thống nhất chung.
Regular Expression bao gồm tập hợp các ký tự, toán tử hay ký hiệu toán học nhằm biểu thị một chuỗi theo cấu trúc chung mà mọi người học theo. Có thể xem Regular Expression như một loại tiếng lóng dùng chung trong lập trình.
Bạn có thể trích lọc một hay nhiều chuỗi có cấu trúc chung từ một đoạn văn bản hay một chuỗi ra.
Bạn có thể tìm kiếm, thay đổi nội dung của chuỗi một cách dễ dàng. Thay vì phải ngồi cắt chuỗi mỏi mệt như trước đây.
Từ đây, với Regular Expression. Bạn hoàn toàn có thể trích lọc dữ liệu từ các đoạn html theo ý.
Cùng nhau tìm hiểu cách sử dụng Regular Expression cơ bản với Kteam nhé.
Nội dung
Để đọc hiểu bài này tốt nhất các bạn nên có kiến thức cơ bản về các phần:
- Biết sơ về lập trình
- Hiểu về chuỗi
- Có khả năng tìm kiếm thêm thông tin trên internet tốt
Trong bài học này, chúng ta sẽ cùng tìm hiểu các vấn đề:
- Các ký hiệu của Regular Expression
- Một số lớp hỗ trợ trong Regular Expression
Các ký hiệu của Regular Expression
Trước khi tìm hiểu về các ký hiệu chúng ta cùng xem qua một ví dụ mẫu để nắm được cấu trúc chung của Regular Expression
Chuỗi mẫu:
-howkteam.com-10092016-
Pattern:
\d{8}
Kết quả tìm kiếm:
10092016
Một cách nhìn khác:
-howkteam.com-10092016-
Hay một cách dễ nhớ
-howkteam.com-\d{8}-
Trong đó
\d là ký hiệu biểu thị cho số
{8} là biểu thị ký tự trước đó xuất hiện 8 lần
Vậy có thể đọc câu pattern này là: Tìm ra chuỗi con là dãy 8 số liên tiếp nhau.
>>> kết quả là trùng khớp.
Nếu bạn thay số 8 thành số 6 tức là pattern thành :
\d{6}
Thì kết quả sẽ thành 100920 hay
-howkteam.com-10092016-
Hay một cách dễ nhớ
-howkteam.com-\d{6}16-
Hay có thể mường tượng Regular Expression này như string.Format
Từ đây bạn có thể nhận thấy. Regular Expression bản chất là tìm ra một hoặc nhiều chuỗi con thỏa mãn cấu trúc chung được định ra.
Hay hiểu cách khác. Regular Expression là một tập khuôn mẫu định dạng chuỗi. Nhằm tìm kiếm chuỗi con một cách dễ dàng từ cấu trúc định dạng. (@@ càng đọc càng ngu người. Thôi tốt nhất không nên đọc dòng này. Xóa dòng này ra khỏi não nha mọi người).
Bảng các ký hiệu Regular Expression thông dụng
Mình sẽ dùng phần mềm RegEx tester để demo cho các bạn xem cách dùng Regular Expression nhé.
Link tải phần mềm ở cuối bài viết. (Tại website www.howteam.com)
Pattern .
Đại diện cho một ký tự bất kỳ. Ngoại trừ ký hiệu \n
Chuỗi mẫu:
-howkteam.com-10092016-
Pattern:
.
Kết quả:
Danh sách các ký tự xuất hiện trong chuỗi mẫu: {-,h,o,w,k,...,1,6,-}
Cách nhìn khác:
Lấy ra từng từ bên trong chuỗi mẫu.
Hình minh họa:
Pattern \d
Đại diện cho ký tự số. Tương đương pattern [0-9].
Chuỗi mẫu:
-howkteam.com-10092016-
Pattern:
\d
Kết quả:
Danh sách các số xuất hiện trong chuỗi mẫu: {1,0,0,9,2,0,1,6}
Cách nhìn khác:
Lấy ra từng số bên trong chuỗi mẫu.
Hình minh họa:
Pattern \D
Ký tự không phải số. Hay có thể hiểu là phủ định của \d
Chuỗi mẫu:
-howkteam.com-10092016-
Pattern:
\D
Kết quả:
Pattern \s
Ký tự khoảng trắng. Tương đương [\f\n\r\t\v]
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
com\s1009
Kết quả:
Pattern \S
Ký tự không phải khoảng trắng. Tương đương phủ định của \s hay tương đương [^\f\n\r\t\v]
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
\S
Kết quả:
Pattern \w
Ký tự word (gồm chữ cái và chữ số, dấu gạch dưới _ ) tương đương [a-zA-Z_0-9]
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
\w
Kết quả:
Pattern \W
Ký tự không phải word. Tương đương phủ định của \w hay [^a-zA-Z_0-9]
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
\W
Kết quả:
Pattern ^
Bắt đầu một chuỗi hay một dòng
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
^-howkteam
Kết quả:
Pattern $
Kết thúc một chuỗi hay một dòng
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
16-$
Kết quả:
Pattern \A
Bắt đầu môt chuỗi
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
\A-howkteam
Kết quả:
Pattern \z
Kết thúc một chuỗi
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
16-\z
Kết quả:
Pattern |
Ký tự so trùng tương đương với or. Dùng để kết hợp nhiều điều kiện.
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
k|h|9
Kết quả:
Pattern [abc]
Khớp với một ký tự nằm trong nhóm này là a hay b hay c đều được.
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
[k9h]
Kết quả:
Pattern [a-z]
Khớp với ký tự trong khoảng a đến z. a và z là ký tự hiện hữu trong bảng ASCII.
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
[1-8]
Kết quả:
Pattern [^abc]
Không trùng bất kỳ ký tự a b hay c. Tương đương phủ định của [abc]
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
[^1-8]
Kết quả:
Pattern ()
Xác định một group. Một biểu thức đơn lẻ trong pattern.
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
([0-3])|([5-7])
Lấy ra tất cả các số trong khoảng [0-3] hoặc trong khoảng [5-7]
Kết quả:
Pattern ?
Khớp với từ đứng trước xuất hiện 0 hay 1 lần.
Chuỗi mẫu:
-howkteam.com 10092016-
Lấy ra tất cả số 1 xuất hiện 0 hay 1 lần
Pattern:
1?
Kết quả:
Pattern *
Khớp với từ đứng trước 0 lần trở lên.
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
1*
Kết quả:
Pattern +
Khớp với từ đứng trước 1 lần trở lên.
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
1+
Kết quả:
Pattern {n}
Với n là số. Khớp với từ đứng trước xuất hiện đúng n lần.
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
0{2}
Lấy ra các kết quả là một cặp số 0 liền nhau.
Hãy thử với n là một giá trị số khác nhé.
Kết quả:
Pattern {n,}
Với n là số. Khớp với từ đứng trước xuất hiện đúng n lần trở lên.
Chuỗi mẫu:
-howkteam.com 10092016-
Pattern:
0{1,}
Kết quả:
Pattern {m,n}
Với m và n là số. Khớp với từ đứng trước xuất hiện từ m đến n lần.
Chuỗi mẫu:
-howkteam.com 100010092016-
Pattern:
0{1,2}
Kết quả:
Một số lớp hỗ trợ trong Regular Expression
Match và MatchCollection
Khi áp dụng một biểu thức quy tắc lên một chuỗi mẫu nào đó thì kết quả trả về có thể là nhiều chuỗi con thoả mãn biểu thức quy tắc trên. Khi đó các chuỗi con sẽ được lưu vào trong 1 tập hợp có tên là MatchCollection, mỗi phần tử trong tập hợp là 1 biến có kiểu Match.
MatchCollection là 1 kiểu tập hợp chứa danh sách các đối tượng kiểu Match. Vì đây cũng là 1 tập hợp bình thường nên có thể thao tác như các tập hợp khác.
Một đối tượng kiểu Match sẽ chứa 1 chuỗi con kết quả, để xem chuỗi con kết quả này ta sẽ gọi phương thức ToString(). Ngoài ra nó cũng có các thuộc tính và phương thức khác như:
Ví dụ sử dụng Match và MatchCollection:
Cho chuỗi gốc là “-howkteam.com 10092016-”. Giả sử bạn muốn lấy ra tất cả các số trong chuỗi. Vậy pattern của chúng ta đơn giản chỉ là “\d”.
Nếu bạn chỉ viết code đơn gian thế này:
Thì kết quả sẽ như sau:
Chúng ta mong muốn lấy ra tất cả các số chứ không phải 1 số thế này! Đến đây có bạn sẽ làm như sau:
Kết quả khi chạy đoạn code trên:
Kết quả có vẻ như ý rồi nhưng ta có thể thấy code không mấy gọn gàng cũng như mất thời gian xử lý ở chỗ hàm NextMatch().
Đến đây ta thử sử dụng MatchCollection đã được .NET hỗ trợ sẵn xem thế nào:
Để ý là lúc này ta dùng hàm Matches() để lấy kết quả chứ không phải Match(). Matches() trả về 1 tập hợp các đối tượng Match (MatchCollection) nên ta có thể dùng foreach để duyệt tập hợp (cú pháp của foreach các bạn có thể tham khảo bài FOREACH TRONG C# trong series LẬP TRÌNH C# CƠ BẢN)
Kết quả khi chạy vẫn giống như cách trên:
Lưu ý:
Nếu như không tìm thấy chuỗi con phù hợp thì sẽ trả về 1 đối tượng Match có giá trị rỗng chứ không phải null. Khi đó để kiểm tra có giá trị hay không ta sẽ sử dụng:
Group và GroupCollection
Group trong Regular Expression là chỉ cách ta gom nhóm các biểu thức lại thành cụm và có thể đặt tên cho nhóm để dễ quản lý và thao tác.
Lớp Group là 1 lớp đại diện cho 1 gom nhóm trong biểu thức. Có 1 điểm chúng ta nên biết là lớp Group là lớp cha của lớp Match!
Tại sao lại có khái niệm này? – Bởi vì:
- Trong 1 kết quả trùng khớp sẽ có thể chứa nhiều thông tin khác nhau và ta mong muốn các thể lấy ra từng thành phần nhỏ trong đó mà không phải dùng thêm 1 biểu thức chính quy nào nữa.
- Và trong biểu thức chính quy ban đầu ta sẽ gom nhóm các thành phần con thành các group và đặt tên cho chúng như vậy khi lấy được 1 chuỗi kết quả ta muốn lấy các thành phần con bên trong đó thì ta chỉ cần gọi chúng thông qua tên đã đặt.
Cú pháp:
(?<tên group>)
Trong đó:
( ): là cú pháp gom nhóm các biểu thức
?<tên group>: là cú pháp đặt tên cho group. Bạn có thể không đặt tên cho group cũng được. Lưu ý là tên group bạn phải viết liền không dấu và nên tuân theo quy tắc đặt tên.
Ví dụ:
Để lấy ra chuỗi giờ phút giây ta có thể làm như sau:
“\d+:\d+:\d+”
Nhưng nếu bây giờ mình muốn lấy ra giờ, phút, giây riêng để xử lý thì phải làm sao?
Nếu viết 3 biểu thức thì khá dài dòng. Khi đó ta sử dụng group và đặt tên cho chúng như sau:
(?<hours>\d+):(?<minutes>\d+):(?<seconds>\d+)
Trong đó “hours”, “minutes”, “seconds” là tên do mình đặt cho 3 group.
Để lấy ra danh sách các gom nhóm trong 1 chuỗi con kết quả ta dùng thuộc tính “Groups” trong lớp Match. Thuộc tính này trả về 1 GroupCollection. GroupCollection là 1 lớp chứa danh sách các gom nhóm trong biểu thức, mỗi phần tử của danh sách là 1 đối tượng kiểu Group.
Ví dụ sử dụng Group và GroupCollection:
Kết quả khi chạy chương trình trên:
.NET đã hỗ trợ chúng ta truy xuất các phần tử trong danh sách GroupCollection thông qua chỉ số phần tử là tên các group chúng ta đã đặt trong biểu thức ở trên.
Capture và CaptureCollection
Mỗi khi tìm thấy bất kỳ 1 chuỗi con nào (bao gồm cả các group) thì C# sẽ bắt nó lại và lưu vào 1 đối tượng có kiểu Capture. Và danh sách tất cả các Capture chính là 1 CaptureCollection.
Một điểm cần biết nữa là Capture là lớp cha của lớp Group!
Tại sao lại có lớp Capture này? – Câu trả lời sẽ nằm trong tình huống sau:
- Cho chuỗi sau “10:30:15 IBM 192.168.1.2 INTEL” hãy viết biểu thức lấy ra giờ phút giây, địa chỉ ip và tên công ty.
Lúc này ta sẽ có biểu thức sau:
“(?<times>(\d|:)+)\s(?<company>\S+)\s(?<ip>(\d|\.)+)\s(?<company>\S+)”
Lưu ý: là mình sẽ không tập trung vào giải thích chi tiết biểu thức mà tập trung vào cách sử dụng các lớp.
Ở đây mình có 2 tên công ty bên trong nên mình đặt chung 1 tên group là company với mong muốn lấy ra 2 tên công ty từ group.
Chương trình kiểm tra:
Nhưng khi chạy chương trình kết quả lại như thế này:
Ta thấy có tới 2 công ty thoả mãn là INTEL và IBM nhưng chương trình chỉ in ra được INTEL. Chúng ta có thể kiểm tra bằng phần mềm RegEx Tester để chắc rằng biểu thức mình viết đúng:
Các bạn hãy để ý chỗ Group 4 (company) trong hình. Rõ ràng ta lấy ra được 2 giá trị nhưng chỉ hiển thị được giá trị sau cùng.
Đến đây có bạn sẽ nói rằng tại sao không đổi tên group khác đi là xong? Câu trả lời là trong ví dụ trên mình chỉ có 2 công ty nhưng giả sử có đến 100 công ty trong chuỗi thì sao? Bạn phải đặt 100 biến khác nhau?
Vì thế chúng ta sẽ tận dụng đặc điểm của Capture và sử dụng chúng để giải quyết.
Chương trình sẽ như sau:
Ở đây để lấy ra danh sách các Capture (CaptureCollection) ta sử dụng thuộc tính Captures.
Kết quả khi chạy đoạn code trên:
Tải phần mềm
Bạn có thể tải phần mềm RegEx tester tại link bên dưới:
Kết luận
Nội dung bài này giúp các bạn nắm được:
- Các ký hiệu của Regular Expression
- Một số lớp hỗ trợ trong Regular Expression
Như từ giờ bạn hoàn toàn tự tin để CRAWL DATA TỪ WEBSITE hay các chuỗi lớn rồi nhé.
Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử thách – Không ngại khó”.
Tải xuống
Tài liệu
Nhằm phục vụ mục đích học tập Offline của cộng đồng, Kteam hỗ trợ tính năng lưu trữ nội dung bài học Regular Expression trong C# dưới dạng file PDF trong link bên dưới.
Ngoài ra, bạn cũng có thể tìm thấy các tài liệu được đóng góp từ cộng đồng ở mục TÀI LIỆU trên thư viện Howkteam.com
Đừng quên like và share để ủng hộ Kteam và tác giả nhé!

Thảo luận
Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng.
Nội dung bài viết
- Dẫn nhập
- Nội dung
- Các ký hiệu của Regular Expression
- Pattern .
- Pattern \d
- Pattern \D
- Pattern \s
- Pattern \S
- Pattern \w
- Pattern \W
- Pattern ^
- Pattern $
- Pattern \A
- Pattern \z
- Pattern |
- Pattern [abc]
- Pattern [a-z]
- Pattern [^abc]
- Pattern ()
- Pattern ?
- Pattern *
- Pattern +
- Pattern {n}
- Pattern {n,}
- Pattern {m,n}
- Một số lớp hỗ trợ trong Regular Expression
- Tải phần mềm
- Kết luận
- Tải xuống
- Thảo luận
Tác giả/Dịch giả
Khóa học
Bạn mới bắt đầu học lập trình? Bạn đang muốn học thêm ngôn ngữ lập trình mới? C# là lựa chọn hoàn hảo để đáp ứng các nhu cầu trên.
Ngôn ngữ C# là một ngôn ngữ mới, cấu trúc rõ ràng, dễ hiểu và dễ học. C# thừa hưởng những ưu việt từ ngôn ngữ Java, C, C++ cũng như khắc phục được những hạn chế của các ngôn ngữ này. C# là ngôn ngữ lập trình hướng đối tượng được phát triển bởi Microsoft, được xây dựng dựa trên C++ và Java.
Khoá học lần này sẽ mang đến toàn bộ những kiến thức cơ bản về C#. Chào mừng các bạn đã đến với khoá học LẬP TRÌNH C# CƠ BẢN của Kteam.
mọi người cho em hỏi với ạ. Tại sao trong phần pattern của company bài cuối lại chỉ có \S thôi ạ. Tức là sao nó không lấy cả 192.168.1.2 làm tên công ty hay phần giờ đó. Em cảm ơn ạ.
EM xin trích lại phần code trong video
Regex RE = new Regex(@"(?<times>(\d|:)+)\s" + @"(?<company>\S+)\s" + @"(?<ip>(\d|\.)+)\s" + @"(?<company>\S+)");
foreach (Match item in RE.Matches("10:30:15 IBM 192.168.1.2 INTEL"))
{
Console.WriteLine(" time: " + item.Groups["times"]);
Console.WriteLine(" ip: " + item.Groups["ip"]);
Console.Write(" company: ");
/*
Lấy ra tất cả các capture bắt được trong group company và duyệt lần lượt chúng
* Sau đó ta có thể sử dụng hàm ToString() hoặc thuộc tính Value để lấy giá trị của Capture
*/
foreach (Capture i in item.Groups["company"].Captures)
{
Console.Write(i.ToString() + " ");
}
}
Admin ơi cho e hỏi, xong bài này là học luôn khoá OOP hay là khoá C# nâng cao vậy ạ??
a ơi cho e xin bài tập bài này với ạ
tải phần mềm ở đâu v ạ?
Trời ơi, bài này hay lắm luôn. Hồi đó giờ cắt chuỗi mà phức tạp toàn ngồi suy nghĩ cách để substring, thực sự tốn thời gian mà cực nữa. Phải xem lại bài này nhiều lần để quen. Rất cảm ơn howkteam về series bài học lập trình, nó rất trực quan và dễ hiểu. Lười xem video thì đọc bài viết cũng cực kỳ dễ hiểu và rất dễ theo dõi, mọi người tổ chức bài viết rất khoa học.