1

I'm trying to find a regex formula for these HTML nodes:

first: Need the inner html value

<span class="profile fn">Any Name Here</span>

second: need the title value

<abbr class="time published" title="2012-08-11T07:02:50+0000">August 10, 2012 at 5:02 pm</abbr>

third: need the inner html value

<div class="msgbody">
Some message here. might contain any character.
</div>

I'm fairly new to regex, and was hoping someone could offer me some guidance with this. I'll be using it with C# if that makes a difference.

Edit:

The HTML I'd be pulling this out of would look like this:

<div class="message">
<div class="from"><span class="profile fn">Name</span></div>
<abbr class="time published" title="2012-08-11T07:02:50+0000">August 10, 2012 at 5:02 pm</abbr>
<div class="msgbody">
Some message
</div>
</div>
4

2 回答 2

1

很多人对使用正则表达式处理 HTML 不屑一顾;但是,我相信如果您的 HTML 确实是规则的并且格式正确,那么您可以成功使用 Regex。

如果你不能保证,那么我建议你查看 HTML Agility Pack,它是一个用于在 C# 中解析 HTML 的库,并且运行良好。

我不在我的电脑上,但我会用建议的正则表达式为你的例子编辑我的答案,至少给你一些尝试。

对于这个:

<span class="profile fn">Any Name Here</span>

尝试

"<span.*?>(?<span>.*?)</span>"

然后,您可以通过正则表达式结果的 Match.Groups("span") 属性访问它。

对于缩写标签:

<abbr class="time published" title="2012-08-11T07:02:50+0000">...snip...</abbr>

很相似

"<abbr.*?title=\"(?<title>.*?)\".*?>"

最后对于 div:

<div class="msgbody">
Some message here. might contain any character.
</div>

是:

"<div.*?>(?<div>.*?)</div>"

对于这个,您可能需要设置 Multiline regex 选项。

关键是 .*? 操作员。

添加问题匹配将贪婪匹配变成前瞻匹配,它告诉正则表达式引擎从找到匹配的位置向前看,而不是找到最后一个匹配然后向后工作;这对于在 HTML 中进行匹配非常重要,因为您将有许多 Chevrons 结束标记。

但是你会遇到的大问题是,如果内部文本或属性中包含'<'或'"'字符会发生什么?很难让正则表达式只匹配平衡的 <> 并且它可以'不要轻易使用引号之间的引号;这就是为什么敏捷包通常是首选的原因。

无论如何,希望这会有所帮助!

编辑:

如何使用命名捕获组

此语法 (?..selector..) 告诉正则表达式引擎将括号之间的任何内容封装成一个可以取出实际匹配对象的值。

所以对于这个 HTML

<span>TEST</span>

您将使用以下代码:

string HTML = "<span>TEST</span>";
Regex r = new Regex("<span>(?<s>.*?)</span>");
var match = r.Match(HTML);

string stuff = match.Groups["s"].Value;
//stuff should = "TEST"

如果您认为您将有多个捕获,那么您将使用此重载的变体:

foreach (Match m in r.Matches(HTML))
{
   string stuff = m.Groups["s"].Value;
}

这应该会产生您需要的答案。

于 2013-06-06T23:03:14.883 回答
0

如果您的 html 始终相同,则可以使用这种丑陋的模式:

"profile fn"[^>]*>(?<name>[^<]+)(?:[^t]+|t(?!itle=))+title="(?<time>[^"]+)(?:[^m]+|m(?!sgbody"))+msgbody">\s*(?<msg>(?:[^<\s]+|(?>\s+)(?!<))+)

结果在m.Groups["name"], m.Groups["time"],m.Groups["msg"]

于 2013-06-06T23:38:15.527 回答