Regex-使用嵌套的div按id查找div的内容

Regex-使用嵌套的div按id查找div的内容,regex,Regex,在别人问之前,我没有做任何截屏 我正试图解析一个html字符串以找到一个具有特定id的div。我这辈子都无法让它工作。以下表达式在一个实例中有效,但在另一个实例中无效。我不确定这是否与html中的额外元素有关 <div\s*?id=(\""|&quot;|&#34;)content(\""|&quot;|&#34;).*?>\s*?(?>(?! <div\s*?> | </div> ) | <div\s*?>(

在别人问之前,我没有做任何截屏

我正试图解析一个html字符串以找到一个具有特定id的div。我这辈子都无法让它工作。以下表达式在一个实例中有效,但在另一个实例中无效。我不确定这是否与html中的额外元素有关

<div\s*?id=(\""|&quot;|&#34;)content(\""|&quot;|&#34;).*?>\s*?(?>(?! <div\s*?> | </div> ) | <div\s*?>(?<DEPTH>) | </div>(?<-DEPTH>) | .?)*(?(DEPTH)(?!))</div>
\s*?(?>(?!)(?)(?)(?)(?)(?)(?)*(?(深度)(?!)
它正在正确地查找具有正确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关键字。您可以找到更多详细信息。

是否需要一个正则表达式来跟踪嵌套在DIV标记中的DIV标记的数量?恐怕这在正则表达式中是不可能的


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

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

Cybis说的是实话。这类内容属于上下文无关语言,它们比正则语言(正则表达式所涵盖的类型)更强大。这涉及到很多计算机科学理论,但让我们先说一句,任何有价值的语言都会有一个库,用于编写您可能应该使用的此类内容。

在.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();
        }
    }
}
使用系统;
使用System.Text.RegularExpressions;
名称空间临时
{
班级计划
{
静态void Main()
{
字符串s=@“
开始做其他的事情
这里还有其他东西
更多的东西
";
正则表达式r=新正则表达式(@“(?()(?>)(?>)*(?>)*)(?(深度)(?!)*”,
RegexOptions.Singleline);
Console.WriteLine(“HTML:\n”);
控制台。写入线(s);
匹配m=r.匹配(s);
如果(m.成功)
{
Console.WriteLine(“\n专用文本:\n”);
Console.WriteLine(m.Groups[4]);
}
Console.ReadLine();
}
}
}

upvoted-这是一个很好的问题,可以让新程序员了解正则表达式所能达到的极限。但是它肯定可以用.net来完成。请看我的回答……它的解析速度可能会比正则表达式快。我知道有递归扩展可以实现这一点,但不能在纯正则表达式中实现。让Microsoft来更改正则语言的定义。