如何编写正则表达式从源HTML中提取名字和姓氏?

时间:2010-08-31 19:47:00

标签: html regex

我一直在努力想出一个将从以下HTML中提取名字和姓氏的正则表达式。我的正则表达不强。

<span id="label_85110"><b>First Name</b></span>
<br/>
    <span id="value_85110">AWeber- Email Parser</span>
    <br/>
</p>
<p>
<span id="label_86004"><b>Last Name</b></span>
<br/>
    <span id="value_86004">Submission</span>
    <br/>
</p>
<p>
<span id="label_85111"><b>Email</b></span>
<br/>
    <span id="value_85111">leslie@dakno.com</span>
    <br/>
</p>
<p>
<span id="label_85540"><b>Phone</b></span>
<br/>
    <span id="value_85540">919-923-7017</span>
    <br/>
</p>

3 个答案:

答案 0 :(得分:3)

@ oliver1,

请注意,正则表达式中的关键字是“常规”。正则表达式与Regular Languages一起使用。

不幸的是,(X)HTML不是常规语言。相反,它是Context Free Language

您无法编写可以正确解析上下文无关语言的RegEx。这是一个经过数学证明的现实; 您无法编写可以正确解析上下文无关语言的RegEx

解决方案:使用XPath

相反,你应该使用XML解析器;您已经在使用XHTML,这意味着您可以使用XPath。 (虽然您在代码段的开头缺少<p>

任何解析器,RegEx或查询如何识别名字和姓氏?我看到的最好的是“<span>元素,它们位于<br />之后”,非常弱。

尽管如此,您仍然可以编写一个XPath查询来查找<span>之后的“<br />元素。”

//br/following-sibling::span/text()

...但是它也会找到EmailPhone的值,因此您只需要前两个结果。

或者,您可以使用id元素上的<span>属性:

//span[@id='value_85110']/text()|//span[@id='value_86004']/text()

如果您可以修改HTML

理想情况下,我的建议是让您的XHTML更具语义性:

<label for="first-name-1">First Name</label>
<span id="first-name-1" class="first-name">Aweber- Email Parser</span>
<label for="last-name-1">Last Name</label>
<span id="last-name-1" class="last-name">Submission</span>
<label for="email-address-1">Email</label>
<span id="email-address-1" class="email-address">leslie@dakno.com</span>
<label for="phone-number-1">Phone</label>
<span id="phone-number-1" class="phone-number">919-923-7017</span>

使用CSS增强它(而不是在整个地方使用<b><br/>)...

label {
    font-weight:bolder;
    display:block;
    maring-top:5px;
}
span {
    display:block;
    maring-bottom:5px;
}

...然后像这样使用XPath查询:

//span[@class='first-name'] | //span[@class='last-name']

答案 1 :(得分:0)

免责声明:这只是问题的答案,而不是为此目的使用正则表达式的认可。

<span[^>]*?><b>First Name(?:<[^>]+?>|\s)+([^<]*?)(?:<[^>]+?>|\s)+?Last Name(?:<[^>]+?>|\s)+([^<]*)[\S\s]+?Phone[\S\s]+?<\/p>

然后只为每场比赛抓住第1组和第2组。用firefox的正则表达式的javascript风格测试了这个。

从哲学的角度来看,如果你有一个支持XPath的HTML解析器,或者如果你确定使用的是有效的XML,那么XPath可能是一个更强大的解决方案,你发布的不是(缺少文档根节点和在开头打开&lt; p&gt;标记。)

答案 2 :(得分:-1)

取决于你的实际正则表达式库或工具的语法,但基本上使用这样的东西:

<span id="label_85110"><b>([^<]+)</b>

然后您可以通过某些API访问第一个匹配组。

提取与此类似的姓氏。

不过,有人可能会说:'正则表达式是从HTML中提取数据的错误工具!! elf!1!'

嗯,这取决于海报。他要求正则表达式。我们不知道细节。也许对于他的受限用例,其他一切都是矫枉过正的。 (例如,一次分析,并保证输入数据始终使用发布的骨架等。)