2013-04-14 26 views
5

Sử dụng regex, tôi muốn có thể lấy văn bản giữa nhiều thẻ DIV. Ví dụ, sau đây:Sử dụng regex để nhận văn bản giữa nhiều thẻ HTML

<div>first html tag</div> 
<div>another tag</div> 

Would đầu ra:

first html tag 
another tag 

Các mô hình regex Tôi đang sử dụng chỉ phù hợp với thẻ div cuối cùng của tôi và nhớ đầu tiên. Code:

static void Main(string[] args) 
    { 
     string input = "<div>This is a test</div><div class=\"something\">This is ANOTHER test</div>"; 
     string pattern = "(<div.*>)(.*)(<\\/div>)"; 

     MatchCollection matches = Regex.Matches(input, pattern); 
     Console.WriteLine("Matches found: {0}", matches.Count); 

     if (matches.Count > 0) 
      foreach (Match m in matches) 
       Console.WriteLine("Inner DIV: {0}", m.Groups[2]); 

     Console.ReadLine(); 
    } 

Output:

Matches tìm thấy: 1

Nội DIV: Đây là một thử nghiệm

+1

Có bắt buộc của công việc này mà bạn sử dụng cụm từ thông dụng? HTML là ngữ cảnh ngữ cảnh miễn phí, không thể phân tích cú pháp bằng các biểu thức chính quy. Thông thường, bạn có thể đến gần, nhưng bạn nên sử dụng trình phân tích cú pháp HTML tốt hơn. Xem http://stackoverflow.com/a/1732454/2022565 –

Trả lời

9

Thay thế mẫu bằng một trận đấu không tham lam

static void Main(string[] args) 
{ 
    string input = "<div>This is a test</div><div class=\"something\">This is ANOTHER test</div>"; 
    string pattern = "<div.*?>(.*?)<\\/div>"; 

    MatchCollection matches = Regex.Matches(input, pattern); 
    Console.WriteLine("Matches found: {0}", matches.Count); 

    if (matches.Count > 0) 
     foreach (Match m in matches) 
      Console.WriteLine("Inner DIV: {0}", m.Groups[1]); 

    Console.ReadLine(); 
} 
+0

Nó tìm thấy cả hai kết quả phù hợp nhưng hiển thị (các) giá trị trống trên chương trình của tôi – ben

+0

Đoạn mã trên phải hoạt động, lưu ý rằng m.Groups [1] và không phải m .Groups [2] khi tôi thay đổi nó một chút vì không có lý do gì để nắm bắt chính thẻ đó. http://www.rubular.com/r/XQrcobmfAK – coolmine

1

Trước hết, hãy nhớ lại r rằng trong tệp HTML bạn sẽ có một biểu tượng dòng mới ("\ n"), mà bạn chưa bao gồm trong Chuỗi mà bạn đang sử dụng để kiểm tra regex của bạn.

Second bằng cách lấy bạn regex:

((<div.*>)(.*)(<\\/div>))+ //This Regex will look for any amount of div tags, but it must see at least one div tag. 

((<div.*>)(.*)(<\\/div>))* //This regex will look for any amount of div tags, and it will not complain if there are no results at all. 

Cũng là một nơi tốt để tìm kiếm loại thông tin này:

http://www.regular-expressions.info/reference.html

http://www.regular-expressions.info/refadv.html

Mayman

0

Ngắn phiên bản là bạn không thể làm điều này một cách chính xác trong mọi tình huống. Sẽ luôn có các trường hợp HTML hợp lệ mà cụm từ thông dụng sẽ không trích xuất thông tin bạn muốn.

Lý do là vì HTML là ngữ cảnh tự do ngữ cảnh, đây là một lớp phức tạp hơn so với cụm từ thông dụng.

Đây là một ví dụ - nếu bạn có nhiều div được xếp chồng lên nhau thì sao?

<div><div>stuff</div><div>stuff2</div></div> 

Các regexes liệt kê như là câu trả lời khác sẽ lấy:

<div><div>stuff</div> 
<div>stuff</div> 
<div>stuff</div><div>stuff2</div> 
<div>stuff</div><div>stuff2</div></div> 
<div>stuff2</div> 
<div>stuff2</div></div> 

vì đó là những gì biểu thức thông thường làm khi họ cố gắng để phân tích cú pháp HTML.

Bạn không thể viết cụm từ thông dụng hiểu cách diễn giải tất cả các trường hợp, bởi vì cụm từ thông dụng không có khả năng làm như vậy. Nếu bạn đang xử lý một tập hợp HTML rất hạn chế cụ thể, nó có thể là có thể, nhưng bạn nên ghi nhớ điều này. thông tin

thêm: https://stackoverflow.com/a/1732454/2022565

1

Bạn đã nhìn Html Agility Pack (xem https://stackoverflow.com/a/857926/618649)?

CsQuery cũng có vẻ khá hữu ích (về cơ bản, sử dụng cú pháp kiểu selector CSS để lấy các phần tử). Xem https://stackoverflow.com/a/11090816/618649.

CsQuery về cơ bản có nghĩa là "jQuery cho C#", đó là khá nhiều tiêu chí tìm kiếm chính xác mà tôi đã sử dụng để tìm nó.

Nếu bạn có thể làm điều này trong trình duyệt web, bạn có thể dễ dàng sử dụng jQuery, sử dụng cú pháp tương tự như $("div").each(function(idx){ alert(idx + ": " + $(this).text()); } (chỉ có bạn rõ ràng là sẽ xuất kết quả vào nhật ký hoặc màn hình hoặc thực hiện cuộc gọi dịch vụ web với nó, hoặc bất cứ điều gì bạn cần làm với nó).

+0

Một downvote mà không có bất kỳ lời giải thích hoặc nhận xét. Cảm ơn! Thực tế là HTML/XML nổi tiếng là một cơn đau ở cổ để đối phó với việc sử dụng Regex. Không phải là bạn không thể làm điều đó, và tôi chắc chắn có nhiều lần, nhưng cú pháp chọn CSS là một đề xuất rõ ràng hơn nhiều. – Craig

1

Tôi nghĩ rằng mã này nên làm việc:

string htmlSource = "<div>first html tag</div><div>another tag</div>"; 
string pattern = @"<div[^>]*?>(.*?)</div>"; 
MatchCollection matches = Regex.Matches(htmlSource, pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline); 
ArrayList l = new ArrayList(); 
foreach (Match match in matches) 
{ 
    l.Add(match.Groups[1].Value); 
} 
7

Như kẻ khác không đề cập đến HTML tags with attributes, đây là giải pháp của tôi để đối phó với điều đó:

// <TAG(.*?)>(.*?)</TAG> 
// Example 
var regex = new System.Text.RegularExpressions.Regex("<h1(.*?)>(.*?)</h1>"); 
var m = regex.Match("Hello <h1 style='color: red;'>World</h1> !!"); 
Console.Write(m.Groups[2].Value); // will print -> World 
Các vấn đề liên quan