Thứ hai, ngày 5 tháng 12 năm 2016

Sử dụng Regular Expression trong C# và .NET Phần 2

Ngày đăng: 1/3/2012, 9:9:34AM | Lượt xem: 3,848
Hot!

 

  Lớp Group

Đôi khi người ta cho là rất tiện khi cho gộp lại những biểu thức con so khớp với nhau như vậy bạn có thể phân tích ngữ nghĩa những đoạn của chuỗi khớp. Ví dụ, có thể bạn muốn so khớp dựa trên địa chỉ IP và cho gộp lại tất cả các IP tìm thấy được bất cứ nơi nào trên đoạn chuỗi.

Lớp Group cho phép bạn tạo những nhóm so khớp dựa trên cú pháp RE, và tượng trưng cho kết quả từ 1 biểu thức gộp nhóm duy nhất.

Một biểu thức gộp nhóm đặt tên cho một nhóm v2 cung cấp 1 RE; bất cứ chuỗi con nào khớp với RE sẽ được đưa vào nhóm. Ví dụ, muốn tạo 1 nhóm IP, bạn có thể viết một RE cho biết một hoặc nhiều digit hay dot theo sau bởi space như sau:

@”(?<ip>(\d|\.)+)\s”

Lớp Match được dẫn xuất từ Group, và có một tập hợp mang tên Groups chứa tất cả các nhóm mà Match tìm thấy.

Lớp Group tượng trưng cho những kết quả thu hoạch được từ 1 thu lượm nhóm duy nhất. Ví Group có thể thu lượm 0, 1 hoặc nhiều chuỗi chữ trong một lần so khớp duy nhất, nó chứa một tập hợp gồm những đối tượng của Capture. Vì Group kế thừa từ Capture, substring bị thu lượm có thể được truy xuất trực tiếp.

Các thể hiện của Group sẽ được trả về bởi thuộc tính Match.Groups(số group) hoặc Match.Groups(“tên group”) nếu cấu trúc gộp nhóm “(?<groupname>)” được dùng đến.

Ví dụ sau đây sử dụng kiến trúc gộp nhóm lồng nhau để thu lượm những chuỗi con gộp thành nhóm:

static void Main(string[] args)
{
    string pattern = "(a(b))c";
    string chuoi = "abdabc";
    //định nghĩa những substring abc,ab,b
    Regex myRegex = new Regex(pattern);
    Match m = myRegex.Match(chuoi);

    for (int i = 0; m.Groups[i].Value != ""; i++)
   {
       Console.WriteLine("{0} co chieu dai {1}", m.Groups[i].Value, m.Groups[i].Length);
   }
}

output 

    abc co chieu dai 3
    ab co chieu dai 2
    b co chieu dai 1

Đoạn mã sau đây sử dụng kiến trúc gộp nhóm có mang tên (name và value) để thu lượm những substrings từ một chuỗi chứa dữ liệu trên 1 dạng thức “DATANAME:VALUE” mà RE bị chẻ ở dâu dấu hai chấm

static void Main(string[] args)
{
    string pattern = @"^(?<name>\w+):(?<value>\w+)";
    Regex myRegex = new Regex(pattern);
    Match m = myRegex.Match("Section:119900");
    for (int i = 0; m.Groups[i].Value != ""; i++)
    {
        Console.WriteLine("{0} co chieu dai {1}", m.Groups[i].Value, m.Groups[i].Length);
    }
}

out put

    Section:119900 co chieu dai 14
    Section co chieu dai 7
    119900 co chieu dai 6

RE sẻ trả về kết xuất sau đây:

    m.Groups[“name”].Value = “Section1”
    m.Groups[“value”].Value = “119900”

Sử dụng cụ thể lớp Group:

static void Main(string[] args)
{
    //một chuỗi ví dụ
    string chuoi = "04:03:27 0 congdongcviet.com";
    //group time = một hoặc nhiều digit hoặc dấu hai chấm
    //theo sau bởi khoảng trắng
    string timePattern = @"(?<time>(\d|\:)+)\s";
    string ipPattren = @"(?<ip>(\d|\.)+)\s";
    string sitePattern = @"(?<site>\S+)";
   string pattern = timePattern +  ipPattren +  sitePattern;
   Regex myRegex = new Regex(pattern);
   //đi lấy tập hợp những so khớp
   MatchCollection matches = myRegex.Matches(chuoi);

   foreach (Match match in matches)
   {
       if (match.Length != 0)
       {
           Console.WriteLine("\nMatch: {0}", match.ToString());
           Console.WriteLine("\nTime: {0}", match.Groups["time"]);
           Console.WriteLine("\nIP: {0}", match.Groups["ip"]);
           Console.WriteLine("\nSite: {0}", match.Groups["site"]);
       }
   }
}

output

    Match: 04:03:27 0 congdongcviet.com
    Time: 04:03:27
    IP: 0
    Site: congdongcviet.com

Theo ví dụ trên, đầu tiên ta tạo một chuỗi để tiến hành dò khớp:

string chuoi = "04:03:27 0 congdongcviet.com";

Chuỗi này có thể là 1 trong nhiều chuỗi được ghi nhận trên một tập tin log của web server như là kết quả dò tìm của CSDL. Trong ví dụ đơn giản này có 3 cột: time – IP – Site, mỗi cột cách nhau bởi một khoảng trắng.

Bạn muốn tạo một đối tượng Regex duy nhất để dò tìm những chuỗi kiểu này, và chặt chúng thành 3 nhóm: time,ip và site :

string timePattern = @"(?<time>(\d|\:)+)\s";
string ipPattren = @"(?<ip>(\d|\.)+)\s";
string sitePattern = @"(?<site>\S+)";
string pattern = timePattern +  ipPattren +  sitePattern;
Regex myRegex = new Regex(pattern);

Ta tập trung xem các ký tự hình thành nhóm:
+Các dấu ngoặc () lo tạo một nhóm. Những gì nằm giữa dấu ngoặc mở (ngay trước dấu ?) và dấu ngoặc đóng (sau dấu + trong trường hợp này) là 1 nhóm đơn độc chưa mang tên.

@"(?<time>(\d|\:)+)\s"

+Chuỗi ?<time> đặt tên nhóm là time và nhóm gắn liền với đoạn văn bản so khớp, là regular expression “(\d|\+)\s”. RE này được suy diễn như sau: “một hoặc nhiều digit hoặc dấu hai chấm theo sau bởi khoảng trắng”.
+Chuỗi ?<ip> đặt tên cho nhóm ip, và ?<site> đặt tên cho nhóm site. Như các ví dụ trước, ví dụ trên cũng đòi hỏi một tập hợp của tát cả các đoạn khớp:

MatchCollection matches = myRegex.Matches(chuoi);

Tiếp theo, cho đi xuyên qua tập hợp matches để lôi ra từng phần tử match của nó:

foreach (Match match in matches)

Nếu chiều dài Length của match lớn hơn 0 có nghĩa là đã tìm thấy một so khớp. Sau đó, thì cho in ra toàn bộ những mục so khớp:

Console.WriteLine("\nMatch: {0}", match.ToString());

Tiếp theo, là đi lấy nhóm time từ tập hợp Groups của match rồi cho in ra nội dung:

Console.WriteLine("\nTime: {0}", match.Groups["time"]);

Với kết xuất:Time:  04:03:27

Tương tự như thế với các nhóm site và ip với kết xuất:

    IP: 0
    Site: congdongcviet.com

Lớp GroupCollection:

Là lớp tượng trưng cho 1 tập hợp gồm toàn những nhóm được thu lượm và trả về một lô những nhóm được thu lượm trong một lần so khớp duy nhất. Collection này thuộc loại read-only và không có phương thức khởi tạo. Các thể hiện của lớp GroupCollection được trả về trong tập hợp mà thuộc tính Match.Groups trả về.
Ví dụ: dò tìm và in ra số những nhóm được thu lượm bởi một RE. Làm thế nào để trích từng thu lượm riêng rẽ trên mỗi thành viên của môt group collection.

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
 
namespace ConsoleApplication1
{
    class Program
    {
       static void Main(string[] args)
       {
           Regex myRegex = new Regex("(a(b))c");
           Match m = myRegex.Match("abdabc");
           Console.WriteLine("So nhom duoc tim thay la: {0}",m.Groups.Count);
       }
   }
}

output

So nhom duoc tim thay la 3

Lớp Cature:

Lớp này chứa những kết quả từ một thu lượm duy nhất dựa trên một expression-con (sub-expression)

Lớp CatureCollection:

Mỗi lần một đối tượng Regex khớp với một subexpression, một thể hiện Capture sẽ được tạo ra, và được thêm vào tập hợp CaptureCollection. Mỗi đối tượng Capture tượng trưng cho một thu lượm (capture) đơn lẻ. Mỗi nhóm sẽ có riêng cho mình một capture collection những mục khớp với subexpression được gắn liền với nhóm.

Lớp CaptureCollection tượng trưng cho một loạt những chuỗi con được thu lượm và trả về một lô những thu lượm được thực hiện chỉ qua một nhóm thu lượm duy nhất. Thuộc tính Captures, một đối tượng của lớp CaptureCollection, được cung cấp như là một thành viên của các lớp Match và Group giúp truy xuất dễ dàng lô các chuỗi con được thu lượm.

Ví dụ: nếu bạn sử dụng regular expression ((a(b)c)+ (dấu + cho biết là một hoặc nhiều chuỗi so khớp) để thu lượm những so khớp từ chuỗi chữ “abcabcabc”. CaptureCollection đối với mỗi matching Group của những substring sẽ chứa 3 thành viên.

Ví dụ sau đây mình dùng đến regular expression (Abc)+ để tìm ra một hoặc nhiều so khớp trên chuỗi “XYZAbcAbcAbcXYZAbcAb”. Ví dụ minh họa việc sử dụng thuộc tính Captures để trả về nhiều nhóm các chuỗi con bị thu lượm:

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
 
namespace ConsoleApplication1
{
    class Program
    {
       static void Main(string[] args)
       {
           string chuoi = "XYZAbcAbcAbcXYZAbcAb";
           string pattern = "(Abc)+";
           Regex myRegex = new Regex(pattern);
           Match m = myRegex.Match(chuoi);

           GroupCollection gc = m.Groups;
           CaptureCollection cc;
           Console.WriteLine("So nhom thu luom duoc = {0}",gc.Count.ToString());
           Console.WriteLine();
           for(int i=0;i<gc.Count;i++)
           {
               cc = gc[i].Captures;
               Console.WriteLine("So capture = " + cc.Count.ToString());
               for(int j=0;j< cc.Count;j++)
               {
                   Console.WriteLine(cc[j] + " bat dau tu ky tu " + cc[j].Index);
               }
               Console.WriteLine();
           }
       }
   }
}

Kết quả:

So nhom thu luom duoc = 2
 
So capture = 1
AbcAbcAbc bat dau tu ky tu 3
 
So capture = 3
Abc bat dau tu ky tu 3
Abc bat dau tu ky tu 6
Abc bat dau tu ky tu 9

Sử dụng lớp CaptureCollection:

Thuộc tính chủ chốt của đối tượng Capture là Length, cho biết chiều dài của chuỗi con bị thu lượm. Khi bạn yêu cầu Match cho biết chiều dài, thì chính Capture.Length bạn tìm thấy, vì Match được thừa kế từ Group, và Group lại được dẫn xuất từ Capture.


Điển hình, bạn sẽ chỉ tìm thấy một Capture đơn độc trong mộg CaptureCollection; nhưng điều này không buộc phải như thế. Điều gì sẽ xảy ra nếu bạn phân tích ngữ nghĩa một chuỗi trong ấy tên công ty có thể xuất hiện hoặc ở hai nơi. Muốn gộp các tên này vào chung thành một match đơn lẻ, bạn tạo nhóm ?<company> ở 2 nơi trong pattern của regular expression.

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
 
namespace ConsoleApplication1
{
    class Program
    {
       static void Main(string[] args)
       {
           string chuoi = "05:04:27 NEVERLAND 1 TNHH";
           string pattern = @"(?<time>(\d|\:)+)\s" +
                           @"(?<company>\S+)\s" +
                           @"(?<ip>(\d|\.)+)\s" +
                           @"(?<company>\S+)";
           Regex myRegex = new Regex(pattern);
           MatchCollection mc = myRegex.Matches(chuoi);

           foreach(Match match in mc)
           {
               if (match.Length!=0)
               {
                   Console.WriteLine("Match: {0}",match.ToString());
                   Console.WriteLine("Time: {0}",match.Groups["time"]);
                   Console.WriteLine("IP: {0}",match.Groups["ip"]);
                   Console.WriteLine("Company: {0}",match.Groups["company"]);
                   Console.WriteLine();
                   foreach(Capture cap in match.Groups["company"].Captures)
                   {
                       Console.WriteLine("cap: {0}",cap.ToString());
                   }
               }
           }
       }
   }
}

Đoạn mã sau cho rảo qua tập hợp Capture đối với nhóm company:

foreach(Capture cap in match.Groups["company"].Captures)

Compiler bắt đầu bằng cách tìm ra tập hợp mà ta rảo qua trên ấy. match là một đối tượng có một tập hợp mang tên Groups. Tập hợp Groups có bộ chỉ mục (indexer) cho phép trích một chuỗi và trả về một đối tượng Group đơn lẻ. Do đó, lệnh sau đây trả về một đối tượng Group đơn lẻ:

match.Groups["company"].Captures

Đến phiên, vòng lặp foreach rảo qua tập hợp Captures, trích mỗi phần tử trong tập hợp và gán cho biến toàn cục cap, thuộc kiểu dữ liệu Capture. Bạn có thể là trên kết xuất có 2 phần tử capture: NEVERLAND và TNHH. Phần tử thứ hai đè chồng lên phần tử đầu trên nhóm, do đó chỉ in ra TNHH, nhưng khi quan sát tập hợp Captures thì bạn thấy có 2 trị bị thu lượm.

Kết quả của ví dụ trên:

    Match: 05:04:27 NEVERLAND 1 TNHH
    Time: 05:04:27
    IP: 1
    Company: TNHH
     
    cap: NEVERLAND
    cap: TNHH

 

 

congdongcviet_neverland
 Chia sẻ qua: 
Hot!
Ý kiến bạn đọc

These items will be permanently deleted and cannot be recovered. Are you sure?

Gallery

image

Maecenas viverra rutrum pulvinar

Maecenas viverra rutrum pulvinar! Aenean vehicula nulla sit amet metus aliquam et malesuada risus aliquet. Vestibulum rhoncus, dolor sit amet venenatis porta, metus purus sagittis nisl, sodales volutpat elit lorem…

Read more

Text Links

Thiết kế logo chuyên nghiệp Insky
DAFABET
W88 w88b.com/dang-ky-tai-khoan-w88
W88
Copyright © 2011 - 2012 vietshare.vn by phamkhuong102@gmail.com doanhkisi2315@gmail.com. All rights reserved.