正则表达式 - 恰好匹配一个标签

时间:2009-04-23 14:08:34

标签: html regex

我有一个正则表达式从HTML字体标记中提取文本:

<FONT FACE=\"Excelsior LT Std Bold\"(.*)>(.*)</FONT>

这一切正常,直到我有一些嵌套的字体标签。而不是匹配

<FONT FACE="Excelsior LT Std Bold">Fett</FONT>

字符串

的结果
<FONT FACE="Excelsior LT Std Bold">Fett</FONT> + <U>Unterstrichen</U> + <FONT FACE="Excelsior LT Std Italic">Kursiv</FONT> und Normal

<FONT FACE="Excelsior LT Std Bold">Fett</FONT> + <U>Unterstrichen</U> + <FONT FACE="Excelsior LT Std Italic"

我如何只获得第一个标签?

4 个答案:

答案 0 :(得分:10)

您需要取消与.*?而非.*的贪婪匹配。

<FONT FACE=\"Excelsior LT Std Bold\"([^>]*)>(.*?)</FONT>

请注意,如果BadAttribute="<FooBar>"标记的FACE属性之后的某个地方存在<FONT>等属性,则会失败。这将混合两个匹配组,如果属性包含</FONT>,它可能会完全混乱。没有办法解决这个问题,因为正则表达式无法计算匹配的标签或引号。所以我绝对同意Tomalak - 尽量避免使用正则表达式来处理XML,HTML和其他类似的标记语言。

答案 1 :(得分:3)

你必须使用非贪婪的明星:

<FONT FACE=\"Excelsior LT Std Bold\"[^>]*>(.*?)</FONT>
                                    ^^^^^  ^^^
                                      |     |
     match any character except ">" --+     +--------+
                                                     |
   match anything, but only up to the next </FONT> --+

关于使用正则表达式处理HTML的常见警告适用:您不应该。

答案 2 :(得分:2)

你需要使用'?'

表示的非贪婪捕获
 <FONT FACE=\"Excelsior LT Std Bold\"(.*?)>(.*?)</FONT>

答案 3 :(得分:0)

<FONT[^>]*Excelsior LT Std Bold[^>]*></FONT>

见Phil Haack的帖子here

这是我对此表达式的C#用法。这用于从HTTP响应中删除特定的CSS和JS文件。

const string CSSFormat = "<link[^>]*{0}[^>]*css[^>]*>";
const string JSFormat = "<script[^>]*{0}[^>]*js[^>]*></script>";

static readonly Regex OverrideCss = new Regex(string.Format(CSSFormat, "override-"), RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
static readonly Regex OverrideIconsJs = new Regex(string.Format(JSFormat, "overrideicons"), RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);