我有一个正则表达式从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"
我如何只获得第一个标签?
答案 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);