在任何人问之前,我没有做任何类型的屏幕抓取。
我正在尝试解析html字符串以找到具有特定ID的div。我不能为我的生活让这个工作。以下表达式在一个实例中有效,但在另一个实例中没有。我不确定它是否与html中的额外元素有关。
<div\s*?id=(\""|"|")content(\""|"|").*?>\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。
答案 0 :(得分:5)
您是否要求使用能够跟踪嵌套在DIV标签内的DIV标签数量的正则表达式?我担心正则表达式是不可能的。
您可以使用正则表达式获取第一个DIV标记的索引,然后循环遍历该字符串中的字符,从该索引开始,并保持打开div标记数的计数。当你遇到一个关闭div标签,并且计数为零时,你在字符串中包含你想要的子字符串的起始和结束索引。
答案 1 :(得分:5)
在.NET中,您可以这样做:
(?<text>
(<div\s*?id=(\"|"|&\#34;)content(\"|"|&\#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=(\""|"|&\#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();
}
}
}
答案 2 :(得分:2)
Cybis说实话。这种东西属于无上下文语言,它比常规语言(正则表达式涵盖的东西)更强大。涉及到很多计算机科学理论,但是让它休息一下,任何有价值的语言都会有一个库,可以用来编写这类你应该使用的东西。
答案 3 :(得分:0)
用什么编程语言?如果它是.Net并且您确定html格式正确,您可以将其加载到XmlDocument或XDocument对象中并对其执行xpath查询。