intTypePromotion=1
zunia.vn Tuyển sinh 2024 dành cho Gen-Z zunia.vn zunia.vn
ADSENSE

Tài Liệu Học Ngôn Ngữ Lập Trình C#_p8

Chia sẻ: Tailieu Upload | Ngày: | Loại File: PDF | Số trang:40

91
lượt xem
20
download
 
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Tham khảo tài liệu 'tài liệu học ngôn ngữ lập trình c#_p8', công nghệ thông tin, kỹ thuật lập trình phục vụ nhu cầu học tập, nghiên cứu và làm việc hiệu quả

Chủ đề:
Lưu

Nội dung Text: Tài Liệu Học Ngôn Ngữ Lập Trình C#_p8

  1. Ngôn Ngữ Lập Trình C# // Tham số thứ ba là true sẽ bỏ qua ki ểm tra ký tự thường – hoa result = string. Compare(s1, s2, true); Console.WriteLine(“Khong phan biet chu thuong va hoa\n”); Console.WriteLine(“S1: {0} , S2: {1}, ket qua : {2}\n”, s1, s2, result); // phương thức nối các chuỗi string s4 = string.Concat(s1, s2); Console.WriteLine(“Chuoi S4 noi tu chuoi S1 va S2: {0}”, s4); // sử dụng nạp chồng toán tử + string s5 = s1 + s2; Console.WriteLine(“Chuoi S5 duoc noi tu chuoi S1 va S2: {0}”, s5); // Sử dụng phương thức copy chuỗi string s6 = string.Copy(s5); Console.WriteLine(“S6 duoc sao chep tu S5: {0}”, s6); // Sử dụng nạp chồng toán tử = string s7 = s6; Console.WriteLine(“S7 = S6: {0}”, s7); // Sử dụng ba cách so sánh hai chuỗi // Cách 1 sử dụng một chuỗi để so sánh với chuỗi còn l ại Console.WriteLine(“S6.Equals(S7) ?: {0}”, s6.Equals(s7)); // Cách 2 dùng hàm của l ớp string so sánh hai chuỗi Console.WriteLine(“Equals(S6, s7) ?: {0}”, string.Equals(s6, s7)); // Cách 3 dùng toán tử so sánh Console.WriteLine(“S6 == S7 ?: {0}”, s6 == s7); // Sử dụng hai thuộc tí nh hay dùng l à chỉ mục và chi ều dài của chuỗi Console.WriteLine(“\nChuoi S7 co chieu dai la : {0}”, s7.Length); Console.WriteLine(“Ky tu thu 3 cua chuoi S7 la : {0}”, s7[2] ); // Ki ểm tra xem một chuỗi có kết thúc với một nhóm ký // tự xác đị nh hay không Console.WriteLine(“S3: {0}\n ket thuc voi chu CNTT ? : {1}\n”, s3, s3.EndsWith(“CNTT”)); Console.WriteLine(“S3: {0}\n ket thuc voi chu Nam ? : {1}\n”, s3, s3.EndsWith(“Nam”)); // Trả về chỉ mục của một chuỗi con Console.WriteLine(“\nTim vi tri xuat hien dau tien cua chu CNTT ”); Console.WriteLine(“trong chuoi S3 là {0}\n”, s3.IndexOf(“CNTT”)); // Chèn từ nhân lực vào trước CNTT trong chuỗi S3 string s8 = s3.Insert(18, “nhan luc ”); Console.WriteLine(“ S8 : {0}\n”, s8); 281 Xử Lý Chuỗi
  2. Ngôn Ngữ Lập Trình C# // Ngoài ra ta có thể kết hợp như sau string s9 = s3.Insert( s3.IndexOf( “CNTT” ) , “nhan luc ”); Console.WriteLine(“ S9 : {0}\n”, s9); } // end Main } // end class } // end namespace -----------------------------------------------------------------------------  Kết quả: So sanh hai chuoi S1: abcd và S2: ABCD ket qua: -1 Khong phan biet chu thuong va hoa S1: abcd , S2: ABCD, ket qua : 0 Chuoi S4 noi tu chuoi S1 va S2: abcdABCD Chuoi S5 duoc noi tu chuoi S1 + S2: abcdABCD S6 duoc sao chep tu S5: abcdABCD S7 = S6: abcdABCD S6.Equals(S7) ?: True Equals(S6, s7) ?: True S6 == S7 ?: True Chuoi S7 co chieu dai la : 8 Ky tu thu 3 cua chuoi S7 la : c S3: Trung Tam Dao Tao CNTT Thanh pho Ho Chi Minh Viet Nam ket thuc voi chu CNTT ? : False S3: Trung Tam Dao Tao CNTT Thanh pho Ho Chi Minh Viet Nam ket thuc voi chu Minh ? : True Tim vi tri xuat hien dau tien cua chu CNTT trong chuoi S3 là 18 S8 : Trung Tam Dao Tao nhan luc CNTT Thanh pho Ho Chi Minh Viet Nam S9 : Trung Tam Dao Tao nhan luc CNTT Thanh pho Ho Chi Minh Viet Nam ----------------------------------------------------------------------------- Như chú ng ta đã xem đoạn chương trình minh họ a trên, chương trình b ắt đầu với ba khai báo chu ỗi: string s1 = “abcd”; string s2 = “ABCD”; 282 Xử Lý Chuỗi
  3. Ngôn Ngữ Lập Trình C# string s3 = @“Trung Tam Dao Tao CNTT Thanh pho Ho Chi Minh Viet Nam”; Hai chu ỗi đầu s1 và s2 đ ược khai báo chuỗ i ký tự b ình thườ ng, còn chu ỗi thứ ba đ ược khai báo là chuỗi nguyên văn (verbatim string) bằng cách sử dụ ng ký hiệu @ trước chuỗ i. Chương trình bắt đ ầu b ằng việc so sánh hai chuỗ i s1 và s2. Phương thức Compare() là phương thức tĩnh củ a lớp string, và phương thứ c nà y đã được nạp chồ ng. Phiên b ản đ ầu tiên của phương thức nạp chồ ng này là lấ y hai chu ỗi và so sánh chúng với nhau: // So sánh hai chuỗi với nhau có phân bi ệt chữ thường và chữ hoa result = string.Compare( s1 ,s2); Console.WriteLine(“So sanh hai chuoi s1: {0} và s2: {1} ket qua: {2} \n”, s1 ,s2 ,result); Ở đ ây việc so sánh có p hân biệt chữ thường và chữ hoa, phương thức trả về các giá trị khác nhau phụ thuộ c vào kết quả so sánh: Mộ t số âm nếu chuỗ i đầu tiên nhỏ hơn chu ỗi thứ hai Giá trị 0 nếu hai chuỗ i b ằng nhau Mộ t số dương nếu chuỗi thứ nhất lớn hơn chuỗi thứ hai. Trong trường hợp so sánh trên thì đưa ra kết quả là chu ỗi s1 nhỏ hơn chuỗ i s2. Trong Unicode cũng như ASCII thì thứ tự củ a ký tự thường nhỏ hơn thứ tự của ký tự hoa: So sanh hai chuoi S1: abcd và S2: ABCD ket qua: -1 Cách so sánh thứ hai dùng phiên b ản nạp chồ ng Compare() lấy ba tham số. Tham số Boolean quyết định bỏ qua hay không bỏ qua việc so sánh phân biệt chữ thường và chữ hoa. Tham số này có thể bỏ qua. Nếu giá trị của tham số là true thì việc so sánh sẽ bỏ qua sự phân biệt chữ thường và chữ hoa. Việc so sánh sau sẽ khô ng quan tâm đến kiểu lo ại chữ: // Tham số thứ ba là true sẽ bỏ qua ki ểm tra ký tự thường – hoa result = string. Compare(s1, s2, true); Console.WriteLine(“Khong phan biet chu thuong va hoa\n”); Console.WriteLine(“S1: {0} , S2: {1}, ket qua : {2}\n”, s1, s2, result); Lú c này thì việc so sánh hoàn toàn giố ng nhau và kết quả trả về là giá trị 0 : Khong phan biet chu thuong va hoa S1: abcd , S2: ABCD, ket qua : 0 Ví dụ minh họ a 10.1 trên tiếp tụ c với việc nối các chuỗ i lại với nhau. Ở đây sử dụng hai cách để nối liền hai chu ỗi. Chúng ta có thể sử dụ ng phương thức Concat() đ ây là p hương thức public static của string: string s4 = string.Concat(s1, s2); Hay cách khác đơn giản hơn là việc sử dụ ng to án tử nối hai chu ỗi (+): string s5 = s1 + s2; Trong cả hai trường hợp thì kết qu ả nố i hai chuỗ i hoàn toàn thành công và như sau: 283 Xử Lý Chuỗi
  4. Ngôn Ngữ Lập Trình C# Chuoi S4 noi tu chuoi S1 va S2: abcdABCD Chuoi S5 duoc noi tu chuoi S1 + S2: abcdABCD Tương tự như vậ y, việc tạo mộ t chu ỗi mới có thể được thiết lập bằng hai cách. Đầu tiên là chú ng ta có thể sử dụng phương thức static Copy() như sau: string s6 = string.Copy(s5); Hoặc thuận tiện hơn chú ng ta có thể sử dụng phương thứ c nạp chồng toán tử (=) thông qua việc sao chép ngầm định: string s7 = s6; Kết qu ả của hai cách tạo trên đ ều hoàn toàn như nhau: S6 duoc sao chep tu S5: abcdABCD S7 = S6: abcdABCD Lớp String của .NET cung cấp ba cách đ ể kiểm tra b ằng nhau giữa hai chuỗ i. Đầu tiên là chú ng ta có thể sử dụng phương thức nạp chồng Equals() đ ể kiểm tra trực tiếp rằng S6 có bằng S7 hay khô ng: Console.WriteLine(“S6.Equals(S7) ?: {0}”, S6.Equals(S7)); Kỹ thu ật so sánh thứ hai là truyền cả hai chu ỗi vào phương thứ c Equals() của string: Console.WriteLine(“Equals(S6, s7) ?: {0}”, string.Equals(S6, S7)); Và phương pháp cuố i cùng là sử dụng nạp chồng toán tử so sánh (=) của String: Console.WriteLine(“S6 == S7 ?: {0}”, s6 == s7); Trong cả ba trường hợp thì kết quả trả về là một giá trị Boolean, ta có kết quả như sau: S6.Equals(S7) ?: True Equals(S6, s7) ?: True S6 == S7 ?: True Việc so sánh bằng nhau giữa hai chuỗi là việc rất tự nhiên và thường được sử dụng. Tuy nhiên, trong mộ t số ngôn ngữ, như VB.NET, khô ng hỗ trợ nạp chồ ng to án tử. Do đó đ ể chắc chắn chúng ta nên sử dụ ng phương thức Equals() là tốt nhất. Các đo ạn chương trình tiếp theo củ a ví dụ 10.1 sử dụng toán tử chỉ mục ([]) đ ể tìm ra ký tự xác đ ịnh trong một chuỗ i. Và dùng thu ộc tính Length đ ể lấy về chiều d ài của to àn bộ một chu ỗi: Console.WriteLine(“\nChuoi S7 co chieu dai la : {0}”, s7.Length); Console.WriteLine(“Ky tu thu 3 cua chuoi S7 la : {0}”, s7[2] ); Kết qu ả là: Chuoi S7 co chieu dai la : 8 Ky tu thu 3 cua chuoi S7 la : c Phương thức EndsWith() hỏ i xem một chuỗi có chứa mộ t chuỗi con ở vị trí cuối cùng hay khô ng. Do vậy, chúng ta có thể hỏ i rằng chu ỗi S3 có kết thú c bằng chu ỗi “CNTT” hay chuỗi “Nam”: // Ki ểm tra xem một chuỗi có kết thúc với một nhóm ký tự xác định hay không 284 Xử Lý Chuỗi
  5. Ngôn Ngữ Lập Trình C# Console.WriteLine(“S3: {0}\n ket thuc voi chu CNTT ? : {1}\n”, s3, s3.EndsWith(“CNTT”)); Console.WriteLine(“S3: {0}\n ket thuc voi chu Nam ? : {1}\n”, s3, s3.EndsWith(“Nam”)); Kết qu ả trả về là lần kiểm tra đ ầu tiên là sai do chuỗi S3 không kết thúc chữ “CNTT”, và lần kiểm tra thứ hai là đúng: S3: Trung Tam Dao Tao CNTT Thanh pho Ho Chi Minh Viet Nam ket thuc voi chu CNTT ? : False S3: Trung Tam Dao Tao CNTT Thanh pho Ho Chi Minh Viet Nam ket thuc voi chu Minh ? : True Phương thức IndexOf() chỉ ra vị trí của một con bên trong mộ t chuỗi (nếu có ). Và phương thức Insert() chèn một chuỗ i con mới vào mộ t bản sao chép củ a chu ỗi ban đ ầu. Đoạn lệnh tiếp theo củ a ví dụ minh họa thực hiện việc xác đ ịnh vị trí xu ất hiện đầu tiên củ a chu ỗi “CNTT” trong chuỗi S3: Console.WriteLine(“\nTim vi tri xuat hien dau tien cua chu CNTT ”); Console.WriteLine(“trong chuoi S3 l à {0}\n”, s3.IndexOf(“CNTT”)); Và kết quả tìm được là 18: Tim vi tri xuat hien dau tien cua chu CNTT trong chuoi S3 l à 18 Chúng ta có thể chèn vào chuỗi từ “nhan luc” và theo sau chuỗi nà y là một khoảng trắng vào trong chu ỗi ban đ ầu. Khi thực hiện thì phương thứ c trả về bản sao của chuỗi đã đ ược chèn vào chu ỗi con mới và đ ược gán lại vào chuỗ i S8: string s8 = s3.Insert(18, “nhan luc ”); Console.WriteLine(“ S8 : {0}\n”, s8); Kết qu ả đưa ra là: S8 : Trung Tam Dao Tao nhan luc CNTT Thanh pho Ho Chi Minh Viet Nam Cuối cù ng, chú ng ta có thể kết hợp một số các phép to án đ ể thực hiện việc chèn như sau: string s9 = s3.Insert( s3.IndexOf( “CNTT” ) , “nhan luc ”); Console.WriteLine(“ S9 : {0}\n”, s9); Kết qu ả cuối cùng cũ ng tương tự như cách chèn bên trên: S9 : Trung Tam Dao Tao nhan luc CNTT Thanh pho Ho Chi Minh Viet Nam Tìm mộ t chuỗi con 285 Xử Lý Chuỗi
  6. Ngôn Ngữ Lập Trình C# Trong kiểu dữ liệu String có cung cấp phương thức Substring() để trích một chuỗ i con từ chu ỗi ban đầu. Cả hai phiên bản đều dù ng một chỉ mục đ ể xác định vị trí b ắt đầu trích ra. Và một trong hai phiên bản dù ng chỉ mụ c thứ hai làm vị trí kết thúc của chuỗ i. Trong ví dụ 10.2 minh họa việc sử dụ ng phương thức Substring() củ a chuỗi.  Ví dụ 10.2 : Sử dụng phương thức Substring(). ----------------------------------------------------------------------------- namespace Programming_CSharp { using System; using System.Text; public class StringTester { static void Main() { // Khai báo các chuỗi để sử dụng string s1 = “Mot hai ba bon”; int ix; // l ấy chỉ số của khoảng trắng cuối cùng ix = s1.LastIndexOf(“ ”); // l ấy từ cuối cùng string s2 = s1.Substring( ix+1); // thi ết l ập l ại chuỗi s1 từ vị trí 0 đến vị trí ix // do đó s1 có giá trị mới l à mot hai ba s1 = s1.Substring(0, ix); // tì m chỉ số của khoảng trắng cuối cùng (sau hai) ix = s1.LastIndexOf(“ ”); // thi ết l ập s3 l à chuỗi con bắt đầu từ vị trí ix // do đó s3 = “ba” string s3 = s1.Substring(ix+1); // thi ết l ập l ại s1 bắt đầu từ vị trí 0 đến cuối vị trí ix // s1 = “mot hai ” s1 = s1.Substring(0, ix); // ix chỉ đến khoảng trắng gi ữa “mot” va “hai ” ix = s1.LastIndexOf(“ ”); // tạo ra s4 l à chuỗi con bắt đầu từ sau vị trí ix, do // vậy có gi á trị l à “hai ” string s4 = s1.Substring( ix+1); // thi ết l ập l ại gi á trị của s1 286 Xử Lý Chuỗi
  7. Ngôn Ngữ Lập Trình C# s1 = s1.Substring(0, ix); // l ấy chỉ số của khoảng trắng cuối cùng, lúc này ix l à –1 ix = s1.LastIndexOf(“ ”); // tạo ra chuỗi s5 bắt đầu từ chỉ số khoảng trắng, nhưng không có khoảng // trắng và i x l à –1 nên chuỗi bắt đầu từ 0 string s5 = s1.Substring(ix +1); Console.WriteLine(“s2 : {0}\n s3 : {1}”, s2, s3); Console.WriteLine(“s4 : {0}\n s5 : {1}\n”, s4, s5); Console.WriteLine(“s1: {0}\n”, s1); }// end Main }// end class }// end namespace -----------------------------------------------------------------------------  Kết quả: s2 : bon s3 : ba s4 : hai s5 : mot s1 : mot ----------------------------------------------------------------------------- Ví dụ minh họ a 10.2 trên khô ng phải là giải pháp tố t đ ể giải quyết vấn đề trích lấ y các ký tự trong một chuỗ i. Nhưng nó là cách gần đ úng tốt nhất và minh họa hữu dụ ng cho kỹ thuật nà y. Chia chuỗi Mộ t giải pháp giải quyết hiệu qu ả hơn đ ể minh họa cho ví dụ 10.2 là có thể sử dụng phương thức Split() của lớp string. Chức năng chính là phân tích một chuỗ i ra thành các chu ỗi con. Để sử dụng Split(), chú ng ta truyền vào mộ t mảng các ký tự phân cách, các ký tự này được dùng đ ể chia các từ trong chu ỗi. Và phương thứ c sẽ trả về mộ t mảng những chuỗ i con.  Ví dụ 10.3 : Sử dụng phương thức Split(). ----------------------------------------------------------------------------- namespace Programming_CSharp { using System; using System.Text; public class StringTester { static void Main() 287 Xử Lý Chuỗi
  8. Ngôn Ngữ Lập Trình C# { // tạo các chuỗi để l àm vi ệc string s1 = “Mot, hai, ba Trung Tam Dao Tao CNTT”; // tạo ra hằng ký tự khoảng trắng và d ấu phẩy const char Space = ‘ ‘; const char Comma = ‘,’; // tạo ra mảng phân cách char[] delimiters = new char[] { Space, Comma }; string output = “”; int ctr = 1; // thực hi ện vi ệc chia một chuỗi dùng vòng l ặp // đưa kết quả vào mảng các chuỗi foreach ( string subString in s1.Split(delimiters) ) { output += ctr++; output += “: ”; output += subString; output += “\n”; }// end foreach Console.WriteLine( output ); }// end Main }// end class } // end namespace -----------------------------------------------------------------------------  Kết quả: 1: Mot 2: 3: hai 4: 5: ba 6: Trung 7: Tam 8: Dao 9: Tao 288 Xử Lý Chuỗi
  9. Ngôn Ngữ Lập Trình C# 10: CNTT ----------------------------------------------------------------------------- Đoạn chương trình bắt đ ầu b ằng việc tạo một chu ỗi để minh họa việc phân tích: string s1 = “Mot, hai, ba Trung Tam Dao Tao CNTT”; Hai ký tự khoảng trắng và dấu phẩy đ ược dùng làm các ký tự phân cách. Sau đó p hương thức Split() được gọ i trong chu ỗi nà y, và truyền kết qu ả vào mỗi vò ng lặp: foreach ( string subString in s1.Split(delimiters) ) Chuỗi output chứa các chuỗ i kết qu ả được khởi tạo là chuỗ i rỗng. Ở đây chú ng ta tạo ra chuỗ i output b ằng bố n b ước. Đầu tiên là nối giá trị củ a biến đếm ctr, tiếp theo là thêm d ấu hai chấm, rồi đưa chuỗ i đ ược chia ra từ chuỗ i ban đầu, và cuối cù ng là thêm ký tự qua dòng mới. Và bố n bước trên cứ được lặp đ ến khi nào chuỗ i khô ng còn chia ra đ ược. Có mộ t vấn đ ề cần nó i là kiểu d ữ liệu string khô ng được thiết kế cho việc thêm vào một chu ỗi định dạng sẵn đ ể tạo ra một chuỗ i mới trong mỗ i vòng lặp trên, nên chú ng ta mới phải thêm vào từng ký tự như vậ y. Mộ t lớp StringBuilder đ ược tạo ra để p hụ c vụ cho nhu cầu thao tác chuỗ i tốt hơn. Thao tá c trên chuỗi dùng StringBuilder Lớp StringBuilder được sử dụng để tạo ra và bổ sung các chu ỗi. Hay có thể nói lớp này chính là phần đ óng gói của một bộ khởi dựng cho mộ t String. Mộ t số thành viên quan trọ ng StringBuilder được tó m tắt trong bảng 10.2 như sau: System.StringBuilder Phương thức Ý nghĩa Truy cập hay gán mộ t số ký tự mà StringBuilder nắm giữ. Capacity() Chỉ mục. Chars() Thiết lập hay truy cập chiều dài củ a chuỗ i Length() Truy cập dung lượng lớn nhất củ a StringBuilder MaxCapacity() Nố i một kiểu đố i tượng vào cuố i của StringBuilder Append() Thay thế định dạng xác đ ịnh b ằng giá trị được đ ịnh d ạng AppendFormat() của mộ t đối tượng. Đảm bảo rằng StringBuilder hiện thời có khả năng tối thiểu EnsureCapacity() lớn như một giá trị xác đ ịnh. Chèn một đố i tượng vào một vị trí xác định Insert() Thay thế tất cả thể hiện củ a mộ t ký tự xác đ ịnh với những Replace() ký tự mới. Bảng 10.2 Phương thức của lớp StringBuilder 289 Xử Lý Chuỗi
  10. Ngôn Ngữ Lập Trình C# Khô ng giống như String, StringBuilder thì dễ thay đổi. Khi chúng ta bổ sung mộ t đối tượng StringBuilder thì chú ng ta đã làm thay đ ổi trên giá trị thật của chuỗi, chứ không phải trên b ản sao. Ví dụ minh họa 10.4 thay thế đố i tượng String bằng một đố i tượng StringBuilder.  Ví dụ minh họa 10.4 : Sử dụng chuỗi StringBuilder. ----------------------------------------------------------------------------- namespace Programming_CSharp { using System; using System.Text; public class StringTester { static void Main() { // khởi tạo chuỗi để sử dụng string s1 = “Mot, hai, ba Trung Tam Dao Tao CNTT”; // tạo ra hằng ký tự khoảng trắng và d ấu phẩy const char Space = ‘ ‘; const char Comma = ‘,’; // tạo ra mảng phân cách char[] delimiters = new char[] { Space, Comma }; // sử dụng StringBuilder để tạo chuỗi output StringBuilder output = new StringBuilder(); int ctr = 1; // chia chuỗi và dùng vòng l ặp để đưa kết quả vào // mảng các chuỗi foreach ( string subString in s1.Split(delimiters) ) { // AppendFormat nối một chuỗi được định dạng output.AppendFormat(“{0}: {1}\n”, ctr++, subString); }// end foreach Console.WriteLine( output ); } } } 290 Xử Lý Chuỗi
  11. Ngôn Ngữ Lập Trình C# ----------------------------------------------------------------------------- Chúng ta chỉ thay phần cuối củ a đo ạn chương trình 10.3. Rõ ràng việc sử dụng StringBuilder thuận tiện hơn là việc sử dụ ng các toán tử bổ sung trong chu ỗi. Ở đây chúng ta sử dụng phương thức AppendFormat() củ a StringBuilder để nố i thêm mộ t chuỗi được định dạng đ ể tạo ra mộ t chuỗi mới. Điều này qu á dễ d àng và khá là hiệu quả. Kết quả chương trình thực hiện cũng tượng tự như ví d ụ minh họa 10.3 dùng String: 1: Mot 2: 3: hai 4: 5: ba 6: Trung 7: Tam 8: Dao 9: Tao 10: CNTT Các biểu thức quy tắc (Regular Expression) Biểu thức qui tắc là một ngôn ngữ mạnh dùng để mô tả và thao tác văn bản. Mộ t biểu thức qui tắc thường được áp dụng cho mộ t chuỗi, hay một tập hợp các ký tự. Thông thường một chuỗ i là to àn bộ văn bản hay tài liệu. Kết quả của việc áp dụng một biểu thức qui tắc đ ến một chuỗ i là trả về một chuỗ i con hoặc là trả về một chuỗ i mới có thể được bổ sung từ mộ t vài phần của chuỗi nguyên thủ y ban đầu. Chúng ta nên nhớ rằng string là khô ng thể thay đổi được và do đó cũng không thể thay đổi b ởi biểu thức qui tắc. Bằng cách áp dụng chính xác biểu thức qui tắc cho chu ỗi sau: Mot, hai, ba, Trung Tam Dao Tao CNTT chú ng ta có thể trả về bất cứ hay t ất cả d anh sách các chuỗ i con (Mot, hai,...) và có thể tạo ra các phiên bản chuỗ i đ ược bổ sung củ a những chu ỗi con (như : TrUng TAM,...). Biểu thức qui tắc này được quyết đ ịnh b ởi cú p háp các ký tự qui tắc của chính bản thân nó . Mộ t biểu thức qui tắc bao gồm hai kiểu ký tự:  Ký tự b ình thườ ng (literal): nhữ ng ký tự này mà chúng ta sử dụng đ ể so khớp với chu ỗi ký tự đích.  Metacharacter: là các biểu tượng đặc biệt, có hành độ ng như là các lệnh trong bộ p hân tích (parser) củ a biểu thức. Bộ phân tích là một cơ chế có trách nhiệm hiểu được các b iểu thức qui tắc. Ví dụ nếu như chú ng ta tạo mộ t biểu thức qui tắc như sau: ^(From|To|Subject|Date): 291 Xử Lý Chuỗi
  12. Ngôn Ngữ Lập Trình C# Biểu thức nà y sẽ so khớp với b ất cứ chu ỗi con nào với những từ như “From”, “To”, “Subject”, và “Date” miễn là những từ này b ắt đầu bằng ký tự dòng mới (^) và kết thú c với dấu hai chấm (:). Ký hiệu dấu mũ (^) trong trường hợp này chỉ ra cho bộ p hân tích biểu thức qui tắc rằng chuỗ i mà chúng ta muốn tìm kiếm phải bắt đ ầu từ dò ng mới. Trong biểu thức nà y các ký tự như “(”,”)”, và “|” là các metacharacter dù ng để nhó m các chu ỗi ký tự bình thường như “From”, “To”,”Subject”, và “Date” và chỉ ra rằng bất cứ sự lựa chọn nào trong số đó đều được so khớp đúng. Ngo ài ra ký tự “^” cũ ng là ký tự metacharacter chỉ ra b ắt đầu dò ng mới. Tóm lại vớ i chu ỗi biểu thức qui tắc như: ^(From|To|Subject|Date): ta có thể p hát biểu theo ngô n ngữ tự nhiên như sau: “Phù hợp với bấ t cứ chuỗi nào bắ t đầu bằng một dòng mới được theo sau bởi mộ t trong bốn chữ From, To, Subject, Date và theo sau là ký tự dấu hai chấm”. Việc trình b ày đ ầy đ ủ về biểu thức quy tắc vượt quá phạm vi củ a cuốn sách nà y, do sự đa dạng và khá phức tạp củ a nó . Tuy nhiên, trong phạm vi trình bày củ a chương 10 này, chú ng ta sẽ được tìm hiểu một số các thao tác phổ b iến và hữu dụng củ a biểu thức quy tắc. Sử dụng biểu thứ c quy tắc qua lớp Regex MS.NET cung cấp một hướng tiếp cận hướng đố i tượng (object- o riented approad) cho biểu thức quy tắc để so khớp, tìm kiếm và thay thế chuỗ i. Biểu thức quy tắc củ a ngôn ngữ C# là đ ược xây d ựng từ lớp regexp của ngô n ngữ Perl5. Namspace System.Text.RegularExpressions củ a thư viện BCL (Base Class Library) chứ a đựng tất cả các đối tượng liên quan đ ến biểu thức quy tắc trong mô i trường .NET. Và lớp quan trọng nhất mà biểu thức quy tắc hỗ trợ là Regex. Ta có thể tạo thể hiện củ a lớp Regex và sử dụng mộ t số phương thức tĩnh trong ví dụ minh họ a 10.5.  Ví dụ minh họa 10.5: Sử dụng lớp Regex. ----------------------------------------------------------------------------- namespace Programming_CSharp { using System; using System.Text; using System.Text.RegularExpressions; public class Tester { static void Main() { // khởi tạo chuỗi sử dụng string s1 = “Mot, hai, ba, Trung Tam Dao Tao CNTT”; 292 Xử Lý Chuỗi
  13. Ngôn Ngữ Lập Trình C# // tạo chuỗi bi ểu thức quy tắc Regex theRegex = new Regex(“ |, ”); StringBuilder sBuilder = new StringBuilder(); int id = 1; // sử dụng vòng l ặp để l ấy các chuỗi con foreach ( string subString in theRegex.Split(s1)) { // nối chuỗi vừa tì m được trong biểu thức quy tắc // vào chuỗi StringBuilder theo định dạng sẵn. sBuilder.AppendFormat(“{0}: {1} \n”, id++, subString); } Console.WriteLine(“{0}”, sBuilder); }// end Main }// end class }// end namespace -----------------------------------------------------------------------------  Kết quả: 1: Mot 2: hai 3: ba 4: Trung 5: Tam 6: Dao 7: Tao 8: CNTT ----------------------------------------------------------------------------- Ví dụ minh họ a bắt đ ầu bằng việc tạo một chu ỗi s1, nộ i dung củ a chuỗ i này tương tự như chu ỗi trong minh họ a 10.4. string s1 = “Mot, hai, ba, Trung Tam Dao Tao CNTT”; Tếp theo mộ t biểu thức quy tắc được tạo ra, biểu thức nà y được dù ng đ ể tìm kiếm một chuỗ i: Regex theRegex = new Regex(“ |, ”); Ở đ ây một bộ khởi tạo nạp chồ ng của Regex lấy m ột chuỗ i biểu thức quy tắc như là tham số của nó. Điều này gây ra sự khó hiểu. Trong ngữ cảnh củ a mộ t chương trình C#, cái nào là biểu thức quy tắc: chuỗ i đ ược đưa vào bộ khởi d ựng hay là đối tượng Regex? Thật sự thì chu ỗi ký tự được truyền vào chính là b iểu thức quy tắc theo ý nghĩa truyền thố ng của thuật ngữ nà y. Tuy nhiên, theo quan điểm hướng đ ối tượng của ngô n ngữ C#, đố i mụ c hay tham số của bộ khở i tạo chỉ đ ơn thuần là chuỗ i ký tự, và chính Regex mới là đối tượng biểu thức quy tắc! 293 Xử Lý Chuỗi
  14. Ngôn Ngữ Lập Trình C# Phần còn lại củ a chương trình thực hiện giố ng như ví dụ minh họ a 10.4 trước. Ngoại trừ việc gọi phương thứ c Split() củ a đố i tượng Regex chứ không phải củ a chuỗ i s1. Regex.Split() hành đ ộng cũ ng tương tự như cách String.Split(). Kết quả trả về là mảng các chuỗ i, đây chính là các chuỗi con so khớp tìm được theo mẫu đ ưa ra trong theRegex. Phương thức Regex.Split() là phương thức được nạp chồng. Phiên b ản đơn giản được gọi trong thể hiện củ a Regex đ ược dùng như trong ví dụ 10.5. Ngoài ra còn có mộ t phiên bản tĩnh của phương thức này. Phiên bản nà y lấy một chuỗ i đ ể thực hiện việc tìm kiếm và một mẫu để so khớp. Tiếp sau là minh họa 10.6 sử dụ ng phương thức tĩnh  Ví dụ minh họa 10.6: Sử dụng phương thức tĩnh Regex.Split(). ----------------------------------------------------------------------------- namespace Programming_CSharp { using System; using System.Text; using System.Text.RegularExpressions; public class Tester { static void Main() { // tạo chuỗi tì m ki ếm string s1 = “Mot, hai, ba Trung Tam Dao Tao CNTT”; StringBuilder sBuilder = new StringBuilder(); int id = 1; // ở đây không tạo thể hi ện của Regex do sử dụng phương // thức tĩ nh của l ớp Regex. foreach( string subStr in Regex.Split( s1, “ |, ”)) { sBuilder.AppendFormat(“{0}: {1}\n”, id++, subStr); } Console.WriteLine(“{0}”, sBuilder); } } } ----------------------------------------------------------------------------- Kết qu ả của ví dụ minh họa 10.6 hoàn toàn tương tự như minh họa 10.5. Tuy nhiên trong chương trình thì chú ng ta không tạo thể hiện của đố i tượng Regex. Thay vào đó chúng ta sử dụng trực tiếp phương thức tĩnh của Regex là Split(). Phương thức nà y lấ y vào hai tham số , 294 Xử Lý Chuỗi
  15. Ngôn Ngữ Lập Trình C# tham số đầu tiên là chuỗ i đ ích cần thực hiện so khớp và tham số thứ hai là chuỗ i biểu thức quy tắc dùng để so khớp. Sử dụng Regex để tìm kiếm tập hợp Hai lớp được thêm vào trong namespace .NET cho phép chú ng ta thực hiện việc tìm kiếm một chuỗ i một cách lập đ i lặp lại cho đến hết chuỗi, và kết quả trả về là mộ t tập hợp. Tập hợp được trả về có kiểu là MatchCollection, bao gồ m không có hay nhiều đố i tượng Match. Hai thuộ c tính quan trọng củ a những đ ối tượng Match là chiều d ài và giá trị củ a nó , chú ng có thể được đọc như trong ví dụ minh họ a 10.7 dưới đây.  Ví dụ minh họa 10.7: Sử dụng MatchCollection và Match. ----------------------------------------------------------------------------- namespace Programming_CSharp { using System; using System.Text.RegularExpressions; class Tester { static void Main() { string string1 = “Ngon ngu lap trinh C Sharp”; // tì m bất cứ chuỗi con nào không có khoảng trắng // bên trong và kết thúc là khoảng trắng Regex theReg = new Regex(@”(\S+)\s”); // tạo tập hợp và nhận kết quả so khớp MatchCollection theMatches = theReg.Matches(string1); // l ặp để l ấy kết quả từ tập hợp foreach ( Match theMatch in theMatches) { Console.WriteLine(“Chieu dai: {0}”, theMatch.Length); // nếu tồn tại chuỗi thì xuất ra if ( theMatch.Length != 0) { Console.WriteLine(“Chuoi: {0}”, theMatch.ToString()); }// end if }// end foreach }// end Main }// end class }// end namespace 295 Xử Lý Chuỗi
  16. Ngôn Ngữ Lập Trình C# -----------------------------------------------------------------------------  Kết quả: Chieu dai: 5 Chuoi: Ngon Chieu dai: 4 Chuoi: ngu Chieu dai: 4 Chuoi: lap Chieu dai: 6 Chuoi: trinh Chieu dai: 2 Chuoi: C ----------------------------------------------------------------------------- Ví dụ 10.7 bắt đ ầu bằng việc tạo một chu ỗi tìm kiếm đơn giản: string string1 = “Ngon ngu lap trinh C Sharp”; và mộ t biểu thức quy tắc để thực hiện việc tìm kiếm trên chuỗ i string1: Regex theReg = new Regex(@”(\S+)\s”); Chuỗi \S tìm ký tự không phải ký tự trắng và d ấu cộng chỉ ra rằng có thể có một hay nhiều ký tự. Chuỗ i \s (chữ thường) chỉ ra là kho ảng trắng. Kết hợp lại là tìm một chuỗi khô ng có kho ảng trắng bên trong như ng theo sau cùng là một khoảng trắng. Chúng ta lưu ý khai báo chu ỗi biểu thức quy tắc d ạng chuỗ i nguyên văn để dễ d àng dù ng các ký tự escape như (\). Kết qu ả được trình bày là năm từ đầu tiên đ ược tìm thấy. Từ cuối cùng khô ng đ ược tìm thấy bởi vì nó không đ ược theo sau bởi kho ảng trắng. Nếu chú ng ta chèn mộ t kho ảng trắng sau chữ “Sharp” và trước dấu ngoặc đó ng, thì chương trình sẽ tìm đ ược thêm chữ “Sharp”. Thuộ c tính Length là chiều dài của chuỗi con tìm kiếm đ ược. Chú ng ta sẽ tìm hiểu sâu hơn về thuộ c tính này trong phần sử dụ ng lớp CaptureCollection ở cuố i chương. Sử dụng Regex để gom nhóm Đô i khi lập trình chúng ta cần gom nhóm một số các biểu thức tương tự với nhau theo mộ t quy định nào đó. Ví dụ như chú ng ta cần tìm kiếm địa chỉ IP và nhóm chúng lại vào trong nhó m IPAddresses đ ược tìm thấy bất cứ đâu trong mộ t chuỗi. Lớp Group cho phép chú ng ta tạo những nhó m và tìm kiếm dựa trên biểu thức quy tắc, và thể hiện kết qu ả từ mộ t nhóm biểu thức đ ơn. Mộ t biểu thức nhó m định rõ mộ t nhó m và cung cấp một biểu thức quy tắc, bất cứ chuỗ i con nào được so khớp bởi biểu thức quy tắc thì sẽ được thêm vào trong nhóm. Ví dụ , đ ể tạo một nhó m chúng ta có thể viết như sau: @”(?(\d|\ .)+)\s” 296 Xử Lý Chuỗi
  17. Ngôn Ngữ Lập Trình C# Lớp Match dẫn xu ất từ nhóm Group, và có mộ t tập hợp gọ i là Groups chứa tất cả các nhóm mà Match tìm thấy. Việc tạo và sử dụng tập hợp Groups và lớp Group được minh họa trong ví dụ 10.8 như sau:  Ví dụ minh họa 10.8: Sử dụng lớp Group. ----------------------------------------------------------------------------- namespace Programming_CSharp { using System; using System.Text.RegularExpressions; class Tester { public static void Main() { string string1 = “10:20:30 127.0.0.0 Dolphin.net”; // nhóm thời gian bằng một hay nhi ều con số hay dấu : // và theo sau bởi khoảng trắng. Regex theReg = new Regex(@”(?(\d|\:)+)\s” + // đị a chỉ IP l à một hay nhi ều con số hay dấu chấm theo // sau bởi khoảng trắng @”(?(\d|\.)+)\s” + // đị a chỉ web là một hay nhi ều ký tự @”(?\S+)”); // l ấy một tập hợp các chuỗi được so khớp MatchCollection theMatches = theReg.Matches( string1 ); // sử dụng vòng l ặp để l ấy các chuỗi trong tập hợp foreach (Match theMatch in theMatches) { if (theMatch.Length != 0) { Console.WriteLine(“\ntheMatch: {0}”, theMatch.ToString()); // hi ển thị thời gian Console.WriteLine(“Time: {0}”, theMatch.Groups[“time”]); // hi ển thị đị a chỉ IP Console.WriteLine(“IP: {0}”, theMatch.Groups[“ip”]); // hi ển thị đị a chỉ web site Console.WriteLine(“Site: {0}”, theMatch.Groups[“site”]); }// end if }// end foreach 297 Xử Lý Chuỗi
  18. Ngôn Ngữ Lập Trình C# }// end Main }// end class }// end namespace ----------------------------------------------------------------------------- Ví dụ minh họ a 10.8 bắt đ ầu bằng việc tạo một chuỗi đ ơn giản đ ể tìm kiếm như sau: string string1 = “10:20:30 127.0.0.0 Dolphin.net”; Chuỗi nà y có thể được tìm thấy trong nội dung của các tập tin log ghi nhận các thô ng tin ở web server hay từ các kết qu ả tìm kiếm đ ược trong cơ sở d ữ liệu. Trong ví d ụ đ ơn giản này có ba cộ t, một cột đ ầu tiên ghi nhận thời gian, cộ t thứ hai ghi nhận đ ịa chỉ IP, và cộ t thứ b a ghi nhận đ ịa chỉ web. Mỗ i cột được ngăn cách b ởi khoảng trắng. Dĩ nhiên là trong các ứng d ụng thực tế ta phải giải quyết những vấn đ ề phức tạp hơn nữa, chú ng ta có thể cần phải thực hiện việc tìm kiếm phức tạp hơn và sử dụng nhiều ký tự ngăn cách hơn nữa. Trong ví dụ này, chúng ta mong muốn là tạo ra một đối tượng Regex đ ể tìm kiếm chu ỗi con yêu cầu và phân chú ng vào trong ba nhó m: time, địa chỉ IP, và đ ịa chỉ web. Biểu thức quy tắc ở đây cũ ng khá đơn giản, do đó cũ ng dễ hiểu. Ở đ ây chú ng ta quan tâm đ ến nhữ ng ký tự tạo nhó m như:
  19. Ngôn Ngữ Lập Trình C# Console.WriteLine(“IP: {0}”, theMatch.Groups[“ip”]); // hi ển thị đị a chỉ web site Console.WriteLine(“site: {0}”, theMatch.Groups[“site”]); Ta nhận được kết quả: IP: 127.0.0.0 Site: Dolphin.net Trong ví dụ 10.8 trên thì tập hợp Match chỉ so khớp duy nhất một lần. Tuy nhiên, nó có thể so khớp nhiều hơn nữa trong một chuỗ i. Để làm đ ược đ iều này, chúng ta có thể bổ sung chuỗi tìm kiếm được lấy từ trong một log file như sau: String string1 = “10:20:30 127.0.0.0 Dolphin.net ” + “10:20:31 127.0.0.0 Mun.net ” + “10:20:32 127.0.0.0 Msn.net ”; Chuỗi nà y sẽ tạo ra ba chuỗ i con so khớp được tìm thấ y trong MatchCollection. Và kết quả ta có thể thấy đ ược là: theMatch: 10:20:30 127.0.0.0 Dolphin.net Time: 10:20:30 IP: 127.0.0.0 site: Dolphin.net theMatch: 10:20:31 127.0.0.0 Mun.net Time: 10:20:31 IP: 127.0.0.0 Site: Mun.net theMatch: 10:20:32 127.0.0.0 Msn.net time: 10:20:32 IP: 127.0.0.0 Site: Msn.net Trong ví dụ này phần b ổ sung, thì theMatches chứa ba đối tượng Match. Mỗ i lần lặp thì các chu ỗi con được tìm thấy (ba lần) và chúng ta có thể xu ất ra chuỗ i cũng như từng nhóm riêng bên trong của chu ỗi con đ ược tìm thấy. Sử dụng lớp CaptureCollection Mỗi khi một đố i tượng Regex tìm thấy một chuỗ i con, thì mô t thể hiện Capture được tạo ra và đ ược thêm vào trong mộ t tập hợp CaptureCollection. Mỗ i một đố i tượng Capture thể hiện một chuỗ i con riêng. Mỗi nhóm có một tập hợp các Capture được tìm thấy trong chuỗi con có liên hệ với nhóm. 299 Xử Lý Chuỗi
  20. Ngôn Ngữ Lập Trình C# Thuộ c tính quan trọng củ a đố i tượng Capture là thuộc tính Length, đ ây chính là chiều dài của chu ỗi con được nắm giữ. Khi chú ng ta hỏi Match chiều dài củ a nó , thì chú ng ta sẽ nhận đ ược Capture.Length do Match được d ẫn xuất từ Group và đến lượt Group lại được dẫn xu ất từ Capture. Mô hình kế thừa trong biểu thức quy tắc của .NET cho phép Match thừa hưởng nhữ ng giao diện phương thức và thu ộc tính củ a những lớp cha của nó. Theo ý nghĩa nà y, thì một Group là một Capture (Group is-a Capture), là mộ t đố i tượng Capture đó ng gói các ý tưởng về các nhó m biểu thức. Đến lu ợt Match, nó cũ ng là một Group (Match is-a Group), nó đó ng gói tất cả các nhóm biểu thức con đ ược so khớp trong biểu thức quy tắc (Xem chi tiết hơn trong chương 5: Kế thừa và đ a hình). Thông thường, chúng ta sẽ tìm thấy chỉ một Capture trong tập hợp CaptureCollection; như ng điều này khô ng phải vậ y. Chúng ta thử tìm hiểu vấn đề như sau, ở đ ây chú ng ta sẽ gặp trường hợp là phân tích một chuỗ i trong đó có nhóm tên củ a cô ng ty đ ược xuất hiện hai lần. Để nhó m chúng lại trong chuỗ i tìm thấy chúng ta tạo nhó m ? xu ất hiện ở hai nơi trong mẫu biểu thức quy tắc như sau: Regex theReg = new Regex(@”(?(\d|\:)+)\s” + @”(?\S+)\s” + @”(?(\d|\.)+)\s” + @”(?\S+)\s”); Biểu thức quy tắc này nhóm b ất cứ chuỗi nào hợp với mẫu so khớp time, và cũng như bất cứ chu ỗi nào theo nhóm ip. Giả sử chúng ta dùng chuỗ i sau để làm chuỗ i tìm kiếm: string string1 = “10:20:30 IBM 127.0.0.0 HP”; Chuỗi nà y chứa tên của hai cô ng ty ở hai vị trí khác nhau, và kết qu ả thực hiện chương trình là như sau: theMatch: 10:20:30 IBM 127.0.0.0 HP Time: 10:20:30 IP: 127.0.0.0 Company: HP Điều gì xảy ra? Tại sao nhó m Company chỉ thể hiện giá trị HP. Còn chuỗ i đ ầu tiên ở đâu hay là khô ng được tìm thấ y? Câu trả lời chính xác là mục thứ hai đ ã viết chồng mụ c đ ầu. Tuy nhiên, Group vẫn lưu giữ cả hai giá trị. Và ta dùng tập hợp Capture để lấy các giá trị này.  Ví dụ minh họa 10.9: Tìm hiểu tập hợp CaptureCollection. ----------------------------------------------------------------------------- namespace Programming_CSharp { using System; using System.Text.RegularExpressions; class Test 300 Xử Lý Chuỗi
ADSENSE

CÓ THỂ BẠN MUỐN DOWNLOAD

 

Đồng bộ tài khoản
2=>2