2
<tr><td align=right>Name:</td><td align=left><b><font color=black>Nathan</font></b></td></tr>
<tr><td align=right>Extension:</td><td align=left><b>222</b></td></tr>

我有上面的HTML文本(无法更改),我想要一个返回 3 个捕获组、标签(Name|Extension)字体颜色(black|red)和数据的正则表达式(\w+)

我在返回捕获组 2(字体颜色)时遇到了一些问题。如您所见,它不在表格的“扩展”行中,因此我将捕获组设为可选。当我这样做时,第一行根本不匹配。我已经尝试了很多不同的量词组合的试验和错误,但我仍然无法得到我正在寻找的结果。

这是我到目前为止的模式:(Name|Extension):.*?(?:<font color=(black|red)>)?.*?>(\w+)

我相信它.*?正在消耗可选的捕获组,并且只匹配第 1 组和第 3 组。如果有人可以向我解释我哪里出错了,那就太好了。

编辑:作为一个试图了解更多关于正则表达式的人,如果人们可以将我上面的数据解释为不可变文本而不是 HTML,我将不胜感激。

4

2 回答 2

3

这是您正在寻找的暴行:

 (Name|Extension).*?<b>[<font color=]{0,12}(black|red)?>?(.*?)</.*

它非常脆弱,如果您处理的 HTML 格式与您提供的示例略有不同,我绝对不会期望它能够工作。不过,如果那个 HTML 确实糟糕,我认为你应该没问题。

请注意,这不能被视为 Signor Mendoza 在使用正则表达式解析 HTML 的固有不可能性方面是错误的证据;恰恰相反,这证明他在每一个细节上都是绝对正确的。这不是解析;这是作弊,就像我说的那样,如果您正在使用的源 HTML 与您提供的示例一样丑陋,您只会侥幸逃脱。

测试用例:

 <tr><td align=right>Name:</td><td align=left><b><font color=black>Nathan</font></b></td></tr>
 <tr><td align=right>Extension:</td><td align=left><b>222</b></td></tr>
 <tr><td align=right>Name:</td><td align=left><b><font color=red>Thomas</font></b></td></tr>
 <tr><td align=right>Extension:</td><td align=left><b>223</b></td></tr>
 <tr><td align=right>Name:</td><td align=left><b><font color=black>Frank</font></b></td></tr>
 <tr><td align=right>Extension:</td><td align=left><b>224</b></td></tr>
 <tr><td align=right>Name:</td><td align=left><b><font color=red>Steve</font></b></td></tr>
 <tr><td align=right>Extension:</td><td align=left><b>225</b></td></tr>
 <tr><td align=right>Name:</td><td align=left><b><font color=black>Tony</font></b></td></tr>
 <tr><td align=right>Extension:</td><td align=left><b>226</b></td></tr>

结果:

 Name black Nathan
 Extension  222
 Name red Thomas
 Extension  223
 Name black Frank
 Extension  224
 Name red Steve
 Extension  225
 Name black Tony
 Extension  226
于 2012-10-02T03:06:44.163 回答
3

问题是不情愿的量词。第一个开始.*?不消耗任何内容,允许正则表达式的下一部分尝试匹配 . 之后的 FONT 标记:。它没有找到一个,但这没关系,因为那部分是可选的。然后第二个.*?接管,只消耗它必须的量,直到>(\w+)可以匹配。所以如果有一个FONT 标签,它会被第二个匹配.*?,而不是你想要的可选组。

但是不要费心使量词变得贪婪;它可能会起作用,但更有可能只是失败的效率较低。试试这个:

<td[^>]*>(Name|Extension):</td><td[^>]*><b>(?:<font color=(black|red)>)?([^<]*)<

因为我明确匹配了标签后面的所有标签,所以如果有一个,它就在正确的位置来匹配 FONT 标签。如果它在那里,group(2)将包含颜色;否则它将是null

于 2012-10-02T03:14:40.243 回答