<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)
字体颜色{ {1}}和数据(black|red)
。
我在返回捕获组2(字体颜色)时遇到了一些麻烦。如您所见,它不存在于表的“扩展”行中,因此我将捕获组设置为可选。当我这样做时,它在第一行根本不匹配。我尝试过一些不同的量词组合的试验和错误,但我仍然无法得到我正在寻找的结果。
这是我到目前为止的模式:(\w+)
我相信(Name|Extension):.*?(?:<font color=(black|red)>)?.*?>(\w+)
正在消耗可选的捕获组,只匹配第1组和第3组。如果有人能向我解释我哪里出错了,那就太好了。
编辑:作为试图更多地了解正则表达式的人,如果有人能够将上面的数据解释为不可变文本而不是HTML,我将不胜感激。
答案 0 :(得分: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
答案 1 :(得分:3)
问题在于不情愿的量词。第一个.*?
首先不消耗任何内容,允许正则表达式的下一部分尝试在:
之后立即匹配FONT标记。它没有找到,但没关系,因为该部分是可选的。然后第二个.*?
接管,只消耗尽可能多的费用,直到>(\w+)
匹配为止。因此,如果 是一个FONT标记,它将被第二个.*?
匹配,而不是按照您的意图与可选组匹配。
但是不要费心使量词人贪心; 可能工作,但更有可能失败的效率更低。试试这个:
<td[^>]*>(Name|Extension):</td><td[^>]*><b>(?:<font color=(black|red)>)?([^<]*)<
因为我明确地匹配了标签后面的所有标签,所以它位于正确的位置以匹配FONT标签(如果有的话)。如果它在那里,group(2)
将包含颜色;否则它将是null
。