
Khi dữ liệu cần kiểm tra càng phức tạp thì cú pháp của biểu thức chính quy cũng càng
phức tạp. Ví dụ, dễ dàng kiểm tra dữ liệu nhập chỉ chứa số hay có chiều dài tối thiểu,
nhưng kiểm tra một URL khá phức tạp. Bảng 2.3 liệt kê một số biểu thức chính quy dùng
để kiểm tra các kiểu dữ liệu thông dụng.
Bảng 2.3 Một số biểu thức chính quy thông dụng
Kiểu dữ liệu nhập Mô tả Biểu thức chính quy
Số Chỉ chứa các chữ số thập phân; ví
dụ 5, hoặc 5683874674. ^\d+$
PIN Chứa 4 chữ số thập phân,
ví dụ 1234. ^\d{4}$
Mật khẩu đơn giản Chứa từ 6 đến 8 ký tự; ví dụ ghtd6f
hoặc b8c7hogh. ^\w{6,8}$
Số thẻ tín dụng
Chứa dữ liệu phù hợp với cấu trúc
của hầu hết các loại số thẻ tín dụng,
ví dụ 4921835221552042 hoặc
4921-8352-2155-2042.
^\d{4}-?\d{4}-?\d{4}-
?\d{4}$
Địa chỉ e-mail
[\w-]+ nghĩa là chứa một
hoặc nhiều ký tự word
hoặc dấu gạch ngang, ví dụ
some-body@adatum.com
^[\w-]+@([\w- ]+\.)+[\w-
]+$
HTTP hoặc HTTPS
URL
Dữ liệu là một URL dựa-trên-HTTP
hay dựa-trên-HTTPS, ví dụ
http://www.microsoft.com
^https?://([\w- ]+\.)+[\w-
]+(/[\w- ./ ?%=]*)?$
Một khi đã biết cú pháp của biểu thức chính quy, bạn tạo một đối tượng
System.Text.RegularExpression.Regex bằng cách truyền cho phương thức khởi dựng của
nó chuỗi chứa biểu thức chính quy. Sau đó, gọi phương thức IsMatch của đối tượng
Regex và truyền chuỗi cần kiểm tra, phương thức này trả về một giá trị luận lý cho biết
chuỗi có hợp lệ không. Cú pháp của biểu thức chính quy sẽ chỉ định Regex so trùng toàn
bộ chuỗi hay chỉ so trùng một phần của chuỗi (xem ^, \A, $, và \z trong bảng 2.2)
Phương thức ValidateInput dưới đây minh họa cách kiểm tra chuỗi nhập bằng biểu thức
chính quy:
public static bool ValidateInput(string regex, string input) {

// Tạo đối tượng Regex dựa trên biểu thức chính quy.
Regex r = new Regex(regex);
// Kiểm tra dữ liệu nhập có trùng với biểu thức chính quy hay không.
return r.IsMatch(input);
}
Bạn có thể sử dụng đối tượng Regex để kiểm tra nhiều chuỗi, nhưng không thể thay đổi
biểu thức chính quy được gắn cho nó; bạn phải tạo một đối tượng Regex mới tương ứng
với một cấu trúc mới. Phương thức ValidateInput ở trên tạo ra một đối tượng Regex mới
mỗi lần được gọi, thay vào đó bạn có thể sử dụng phương thức tĩnh nạp chồng IsMatch.
public static bool ValidateInput(string regex, string input) {
// Kiểm tra dữ liệu nhập có trùng với biểu thức chính quy hay không.
return Regex.IsMatch(input, regex);
}
1.1 Sử dụng biểu thức chính quy đã được biên dịch
V
V
Bạn cần giảm thiểu các tác động lên hiệu năng của ứng dụng khi các biểu thức
chính quy phức tạp được sử dụng thường xuyên.
#
#
Khi khởi tạo đối tượng System.Text.RegularExpressions.Regex, hãy truyền
thêm tùy chọn Compiled thuộc kiểu liệt kê System.Text.RegularExpressions.
RegexOptions để biên dịch biểu thức chính quy thành Microsoft Intermediate
Language (MSIL).
Theo mặc định, khi bạn tạo đối tượng Regex, mẫu biểu thức chính quy do bạn xác định
trong phương thức khởi dựng được biên dịch thành một dạng trung gian (không phải
MSIL). Mỗi lần bạn sử dụng đối tượng Regex, bộ thực thi phiên dịch dạng trung gian này
và áp dụng nó để kiểm tra chuỗi. Với các biểu thức chính quy phức tạp được sử dụng
thường xuyên, việc phiên dịch lặp lặp đi lại có thể gây tác động xấu lên hiệu năng của
ứng dụng.
Khi tùy chọn RegexOptions.Compiled được chỉ định, bộ thực thi sẽ biên dịch biểu thức
chính quy thành MSIL. MSIL này được gọi là mã just-in-time (JIT), được biên dịch thành
mã máy nguyên sinh trong lần thực thi đầu tiên, giống như mã assembly thông thường.
Biểu thức chính quy được biên dịch cũng được sử dụng giống như đối tượng Regex, việc
biên dịch chỉ giúp thực thi nhanh hơn.
Tuy nhiên, việc biên dịch biểu thức chính quy cũng có vài nhược điểm. Trước tiên, trình
biên dịch JIT phải làm việc nhiều hơn, dẫn đến chậm quá trình biên dịch, đặc biệt khi tạo
biểu thức chính quy được biên dịch khi ứng dụng khởi động. Thứ hai, biểu thức chính
quy được biên dịch vẫn tồn tại trong bộ nhớ khi không còn được sử dụng nữa, nó không

bị bộ thu gom rác (Garbage Collector) xóa đi như các biểu thức chính quy thông thường.
Vùng nhớ bị chiếm chỉ được giải phóng khi chương trình kết thúc, hoặc khi bạn giải
phóng miền ứng dụng.
Dòng mã sau minh họa cách tạo một đối tượng Regex được biên dịch thành MSIL:
Regex reg = new Regex(@"[\w-]+@([\w-]+\.)+[\w-]+",
RegexOptions.Compiled);
Ngoài ra, phương thức tĩnh Regex.CompileToAssembly cho phép bạn tạo một biểu thức
chính quy được biên dịch và ghi nó vào một assembly khác. Nghĩa là bạn có thể tạo một
assembly chứa các biểu thức chính quy để sử dụng cho nhiều ứng dụng sau này. Để biên
dịch một biểu thức chính quy và lưu nó vào một assembly, thực hiện các bước sau:
1. Tạo một mảng System.Text.RegularExpressions.RegexCompilationInfo đủ lớn để
chứa các đối tượng RegexCompilationInfo, mỗi đối tượng ứng với một biểu thức
chính quy cần được biên dịch.
1. Tạo một đối tượng RegexCompilationInfo cho mỗi biểu thức chính quy và truyền
đối số cho phương thức khởi dựng để xác định các thuộc tính của biểu thức chính
quy này. Các thuộc tính thông dụng là:
• IsPublic⎯giá trị bool xác định lớp biểu thức chính quy được tạo ra có tầm vực
là công khai hay không.
• Name⎯một String xác định tên của lớp.
• Namespace⎯một String xác định không gian tên của lớp.
• Pattern⎯một String xác định mẫu mà biểu thức chính quy sẽ so trùng (xem chi
tiết ở mục 2.5).
• Options⎯một giá trị thuộc kiểu liệt kê System.Text.RegularExpressions.
RegexOptions xác định các tùy chọn cho biểu thức chính quy.
2. Tạo một đối tượng System.Reflection.AssemblyName để xác định tên của assembly
mà phương thức Regex.CompileToAssembly sẽ tạo ra.
3. Gọi phương thức Regex.CompileToAssembly, truyền các đối số là mảng
RegexCompilationInfo và đối tượng AssemblyName.
Quá trình trên tạo ra một assembly chứa các khai báo lớp cho từng biểu thức chính quy
được biên dịch, mỗi lớp dẫn xuất từ Regex. Để sử dụng một biểu thức chính quy đã được
biên dịch trong assembly, bạn cần tạo đối tượng biểu thức chính quy này và gọi các
phương thức của nó giống như khi tạo nó với phương thức khởi dựng Regex bình thường.
Bạn nhớ thêm tham chiếu tới assembly khi sử dụng các lớp biểu thức chính quy nằm
trong nó.
Đoạn mã sau minh họa cách tạo một assembly có tên là MyRegex.dll, chứa hai biểu thức
chính quy có tên là PinRegex và CreditCardRegex:

using System.Text.RegularExpressions;
using System.Reflection;
public class CompiledRegexExample {
public static void Main() {
// Tạo mảng chứa các đối tượng RegexCompilationInfo.
RegexCompilationInfo[] regexInfo = new RegexCompilationInfo[2];
// Tạo đối tượng RegexCompilationInfo cho PinRegex.
regexInfo[0] = new RegexCompilationInfo(@"^\d{4}$",
RegexOptions.Compiled, "PinRegex", "", true);
// Tạo đối tượng RegexCompilationInfo cho CreditCardRegex.
regexInfo[1] = new RegexCompilationInfo(
@"^\d{4}-?\d{4}-?\d{4}-?\d{4}$",
RegexOptions.Compiled, "CreditCardRegex", "", true);
// Tạo đối tượng AssemblyName để định nghĩa assembly.
AssemblyName assembly = new AssemblyName();
assembly.Name = "MyRegEx";
// Tạo các biểu thức chính quy được biên dịch.
Regex.CompileToAssembly(regexInfo, assembly);
}
}
1.2 Tạo ngày và giờ từ chuỗi
V
V
Bạn cần tạo một thể hiện System.DateTime mô tả giờ, ngày được chỉ định
trong một chuỗi.
#
#
Sử dụng phương thức Parse hoặc ParseExact của lớp DateTime.
Có nhiều cách mô tả ngày, giờ; ví dụ 1st June 2004, 1/6/2004, 6/1/2004, 1-Jun-2004 cùng
chỉ một ngày; 16:43 và 4:43 PM cùng chỉ một giờ. Lớp DateTime cung cấp phương thức
tĩnh Parse rất linh hoạt, cho phép tạo thể hiện DateTime từ nhiều cách mô tả khác nhau
trong chuỗi.
Phương thức Parse rất mạnh trong việc tạo đối tượng DateTime từ một chuỗi cho trước.
Nó có thể xử lý một chuỗi chỉ chứa một phần thông tin hay chứa thông tin sai, và thay thế

các giá trị thiếu bằng các giá trị mặc định. Ngày mặc định là ngày hiện tại, giờ mặc định
là 12:00:00 AM. Nếu sau mọi cố gắng, Parse không thể tạo đối tượng DateTime, nó sẽ
ném ngoại lệ System.FormatException. Ví dụ sau minh họa tính linh hoạt của Parse:
// 01/09/2004 12:00:00 AM
DateTime dt1 = DateTime.Parse("Sep 2004");
// 05/09/2004 02:15:33 PM
DateTime dt2 = DateTime.Parse("Sun 5 September 2004 14:15:33");
// 05/09/2004 12:00:00 AM
DateTime dt3 = DateTime.Parse("5,9,04");
// 05/09/2004 02:15:33 PM
DateTime dt4 = DateTime.Parse("5/9/2004 14:15:33");
// 07/10/2004 02:15:00 PM (giả sử ngày hiện tại là 07/10/2004)
DateTime dt5 = DateTime.Parse("2:15 PM");