正则表达式 - 使用嵌套div查找id的div内容

时间:2008-11-13 02:41:30

标签: regex

在任何人问之前,我没有做任何类型的屏幕抓取。

我正在尝试解析html字符串以找到具有特定ID的div。我不能为我的生活让这个工作。以下表达式在一个实例中有效,但在另一个实例中没有。我不确定它是否与html中的额外元素有关。

<div\s*?id=(\""|&quot;|&#34;)content(\""|&quot;|&#34;).*?>\s*?(?>(?! <div\s*?> | </div> ) | <div\s*?>(?<DEPTH>) | </div>(?<-DEPTH>) | .?)*(?(DEPTH)(?!))</div>

正确找到具有正确id的第一个div,但它会在第一个结束div处关闭,而不是相关的div。

<div id="firstdiv">begining content<div id="content">some other stuff
    <div id="otherdiv">other stuff here</div>
    more stuff
    </div>
</div>

这应该带回来

<div id="content">some other stuff
   <div id="otherdiv">other stuff here</div>
   more stuff
</div>

,但出于某种原因,事实并非如此。它被带回来了:

   <div id="content">some other stuff
      <div id="otherdiv">other stuff here</div>

有没有人有更容易表达来处理这个?

为了澄清,这是在.NET中,我正在使用DEPTH关键字。您可以找到更多详细信息here

4 个答案:

答案 0 :(得分:5)

您是否要求使用能够跟踪嵌套在DIV标签内的DIV标签数量的正则表达式?我担心正则表达式是不可能的。

您可以使用正则表达式获取第一个DIV标记的索引,然后循环遍历该字符串中的字符,从该索引开始,并保持打开div标记数的计数。当你遇到一个关闭div标签,并且计数为零时,你在字符串中包含你想要的子字符串的起始和结束索引。

答案 1 :(得分:5)

在.NET中,您可以这样做:

(?<text>
(<div\s*?id=(\"|&quot;|&\#34;)content(\"|&quot;|&\#34;).*?>)

  (?>
      .*?</div>
    |
      .*?<div (?>depth)
    |
      .*?</div> (?>-depth)
  )*)
  (?(depth)(?!))
.*?</div>

您必须使用单行选项。以下是使用控制台的示例:

using System;
using System.Text.RegularExpressions;

namespace Temp
{
    class Program
    {
        static void Main()
        {
            string s = @"
<div id=""firstdiv"">begining content<div id=""content"">some other stuff
  <div id=""otherdiv"">other stuff here</div>
  more stuff
  </div>
</div>";
            Regex r = new Regex(@"(?<text>(<div\s*?id=(\""|&quot;|&\#34;)"
                + @"content(\""|&quot;|&\#34;).*?>)(?>.*?</div>|.*?<div "
                + @"(?>depth)|.*?</div> (?>-depth))*)(?(depth)(?!)).*?</div>",
                RegexOptions.Singleline);
            Console.WriteLine("HTML:\n");
            Console.WriteLine(s);
            Match m = r.Match(s);
            if (m.Success)
            {
                Console.WriteLine("\nCaptured text:\n");
                Console.WriteLine(m.Groups[4]);

            }
            Console.ReadLine();
        }
    }
}

答案 2 :(得分:2)

Cybis说实话。这种东西属于无上下文语言,它比常规语言(正则表达式涵盖的东西)更强大。涉及到很多计算机科学理论,但是让它休息一下,任何有价值的语言都会有一个库,可以用来编写这类你应该使用的东西。

答案 3 :(得分:0)

用什么编程语言?如果它是.Net并且您确定html格式正确,您可以将其加载到XmlDocument或XDocument对象中并对其执行xpath查询。