在任何人问之前,我没有做任何类型的屏幕抓取.
我正在尝试解析一个html字符串以找到具有特定id的div.我不能为我的生活让这个工作.以下表达式在一个实例中有效,但在另一个实例中没有.我不确定它是否与html中的额外元素有关.
<div\s*?id=(\""|"|")content(\""|"|").*?>\s*?(?>(?! <div\s*?> | </div> ) | <div\s*?>(?<DEPTH>) | </div>(?<-DEPTH>) | .?)*(?(DEPTH)(?!))</div>
Run Code Online (Sandbox Code Playgroud)
它正确地找到具有正确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>
Run Code Online (Sandbox Code Playgroud)
这应该带回来
<div id="content">some other stuff
<div id="otherdiv">other stuff here</div>
more stuff
</div>
Run Code Online (Sandbox Code Playgroud)
,但由于某种原因,它不是.它带回来:
<div id="content">some other stuff
<div id="otherdiv">other stuff here</div>
Run Code Online (Sandbox Code Playgroud)
有没有人有一个更容易表达来处理这个?
为了澄清,这是在.NET中,我正在使用DEPTH关键字.你可以在这里找到更多细节.
你是否要求一个能够跟踪嵌套在DIV标签内的DIV标签数量的正则表达式?我担心正则表达式是不可能的.
您可以使用正则表达式来获取第一个DIV标记的索引,然后循环遍历该字符串中的字符,从该索引开始,并保持打开div标记的数量.当您遇到一个关闭的div-tag,并且count为零时,那么您在包含所需子字符串的字符串中有起始和结束索引.
在.NET中,您可以这样做:
(?<text>
(<div\s*?id=(\"|"|&\#34;)content(\"|"|&\#34;).*?>)
(?>
.*?</div>
|
.*?<div (?>depth)
|
.*?</div> (?>-depth)
)*)
(?(depth)(?!))
.*?</div>
Run Code Online (Sandbox Code Playgroud)
您必须使用单行选项.以下是使用控制台的示例:
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=(\""|"|&\#34;)"
+ @"content(\""|"|&\#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();
}
}
}
Run Code Online (Sandbox Code Playgroud)