试试下面的表达式:
(?i)href\s*=\s*"http://(?>((?<InvalidUrlChars>[$]{2})|[^"])*?")(?(InvalidUrlChars)(?!))
编辑:对上述模式的更详细解释:
(?i) - 这是一个内嵌正则表达式选项。它将表达式设置为不区分大小写。(这样“http”将匹配“HTTP”)
(?>...) - 这是一个原子分组结构。它基本上说,任何被组匹配的东西都不能被匹配。正则表达式会尝试许多不同的路径来查看它是否可以得到匹配。例如,如果没有这个分组结构,我用来消除包含“$$”的匹配项的结构将被规避。
(?...) - 一个命名组。
[^"] - 匹配任何不是引号的字符。
(...|...) - 另一种分组结构。正则表达式将尝试使用管道(“|”)之前的模式查找匹配项。如果无法进行匹配,它将使用管道后面的模式再次尝试。
? - 这是一场非贪婪的比赛。使用常规“ ”,正则表达式将尝试尽可能多地匹配。“*?” 将尝试尽可能少地匹配。在尝试匹配一组给定符号之间的文本时,它稍微更有效和更有帮助。
(?(InvalidUrlChars)...|...) - if/else 分组结构。使用这种特殊语法,如果命名组 ("(InvalidUrlChars)") 匹配,则管道前面的表达式将被匹配。否则,管道后面的表达式将被匹配。“else”部分是可选的(我没有使用它)。
(?!) - 否定的前瞻断言。我没有足够的空间来描述环视断言,但可以说这个表达式总是会失败。
因此,总而言之,此表达式将匹配任何 URL,但如果 URL 包含双美元符号 ("$$"),则 InvalidUrlChars 组将触发为“匹配”。在表达式的末尾,如果 InvalidUrlChars 组匹配,则整个匹配将失败,原子组将阻止正则表达式返回并将美元符号视为非引号。
有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/az24scfc
比较以下字符串:
<a href="http://test.com"/>
<a href="http://test.com" alt="test"/>
<a alt="$$" href="http://test.com"/>
<a HREF="HTTP://test.com"/>
<a href=http://test.com />
<a href="https://test.com"/>
<a href="ftp://test.com"/>
<a href="test.com"/>
<a href="http://test$$.com"/>
<a href="http://////invalid*&^%$#@!;"/>
以下将匹配:
href="http://test.com"
href="http://test.com"
href="http://test.com"
HREF="HTTP://test.com"
href="http://////invalid*&^%$#@!;"
编辑:我衷心同意最好使用 HTML 解析器来处理 HTML。正则表达式很糟糕。但是,如果您需要快速解决方案并且您不太关心偶尔的怪癖,那么 Regex 是一个合适的替代品。