我正在使用HTMLAgiltyPack来提取嵌入在发送给我们的查询中的电子邮件地址。有问题的HTML部分采用以下形式:
<div class="queryBody">
<span>
****Query here****
MAY contain paragraphs and lists tags.
</span>
</div>
这是我的代码:
string query = queryHtml.DocumentNode.SelectNodes(
@"//div[@class='queryBody']
/span")[0].InnerText;
string pattern = @"([\w.]+)@([\w.]+)\.([a-z]+)";
Match match = Regex.Match(par, pattern);
string email = "";
if (match.Success)
{
email = match.Value;
}
当<span>
中的HTML包含段落和列表时,会出现问题。在这种情况下,query
将返回一个大字符串,其中包含<p>
和<li>
中的所有换行符。
示例:
<div class="queryBody">
<span>
<p>I am unable to log into my account</p>
<p>Please help me sort out this problem</p>
<p>My email is: rebecca.h@gmail.com</p>
<p>cell: 021901493</p>
</span>
</div>
query
将返回:
I am unable to log into my accountPlease help me sort out this problemMy email is: rebecca.h@gmail.comcell: 021901493
这使得使用我的正则表达式模式提取电子邮件地址非常困难。在使用HtmlAgilityPack遍历HTML节点时,有什么方法可以保留换行符吗?我还能做些什么来成功提取电子邮件地址?
答案 0 :(得分:0)
如果只提取一封电子邮件,您可以使用
var query = queryHtml.DocumentNode.SelectNodes(
@"//div[@class='queryBody']
/span");
var pattern = @"\S+@\S+\.\S+";
var email = "";
if (query != null)
{
var emailNode = query.Descendants().Where(m => Regex.IsMatch(m.InnerText, pattern)).FirstOrDefault();
if (emailNode != null)
{
email = Regex.Match(emailNode.InnerText, pattern).Value;
}
}
重点是找到与电子邮件模式匹配的后代节点(注意我使用的是更通用的模式,匹配1个非空格,@
,1 +非空格,{{ 1}}再次1+非空格),然后提取匹配。
您可以通过收集与该模式匹配的所有节点,然后使用.
获取所有模式匹配,轻松调整多封电子邮件的代码。
答案 1 :(得分:0)
你的正则表达式使用原始html,所以我只使用InnerHtml而不是InnerText。代码就是。
string query = queryHtml.DocumentNode.SelectNodes(
@"//div[@class='queryBody']
/span")[0].InnerHtml;
string pattern = @"([\w.]+)@([\w.]+)\.([a-z]+)";
Match match = Regex.Match(par, pattern);
string email = "";
if (match.Success)
{
email = match.Value;
}
这样可以正确获取地址,因为'&lt;'不在[a-z]。然后,如果你做某些原因需要InnerText我会把它作为一个单独的变量。