我想创建一个匹配包含href属性的开始<a>
标记的正则表达式:
<a href="doesntmatter.com">
它应匹配上述内容,但在添加其他属性时不匹配:
<a href="doesntmatter.com" onmouseover="alert('Do something evil with Javascript')">
通常情况下这很简单,但HTML是经过编码的。所以编码上面的两个,我需要正则表达式来匹配这个:
<a href="doesntmatter.com" >
但不符合这个:
<a href="doesntmatter.com" onmouseover="alert('do something evil with javascript.')" >
假设所有编码的HTML都是“有效的”(没有奇怪的格式错误的XSS技巧),并假设我们不需要遵循任何HTML清理最佳实践。我只需要与A)相匹配的最简单的正则表达式而不是B)。
谢谢!
答案 0 :(得分:2)
首先想到的正则表达式为/<a href=".*?">/
;惰性表达式(.*?
)可用于匹配引号之间的字符串。但是,正如评论中所指出的那样,因为正则表达式由&gt;锚定,所以它也会匹配无效标记,因为仍然会进行匹配。
为了解决此问题,您可以使用atomic grouping。原子分组告诉正则表达式引擎,“一旦你找到了这个组的匹配,接受它” - 这将解决正则表达式返回的问题,并在找不到&gt;后匹配第二个字符串。一个href的结尾。具有原子组的正则表达式如下所示:
/<a (?>href=".*?")>/
使用HTML实体替换字符时,如下所示:
/<a (?>href=".*?")>/
答案 1 :(得分:1)
喂!我最近不得不做类似的事情。我建议首先解码html然后尝试获取你想要的信息。这是我在C#中的解决方案:
private string getAnchor(string data)
{
MatchCollection matches;
string pattern = @"<a.*?href=[""'](?<href>.*?)[""'].*?>(?<text>.*?)</a>";
Regex myRegex = new Regex(pattern, RegexOptions.Multiline);
string anchor = "";
matches = myRegex.Matches(data);
foreach (Match match in matches)
{
anchor += match.Groups["href"].Value.Trim() + "," + match.Groups["text"].Value.Trim();
}
return anchor;
}
我希望有所帮助!
答案 2 :(得分:0)
我不知道一个人与另一个人有什么不同?你只是在寻找你刚才所写的内容,使doesntmatter.com
部分成为你捕获的部分。我想匹配任何内容,直到"
(不是"
?)会出现问题,但你在正则表达式中这样做:
(?:(?!").)*
它实质上意味着:
"""
完整的正则表达式为:
/<a href="(?>(?:[^&]+|(?!").)*)">/s
这比使用非贪婪表达更有效。
感谢Daniel Vandersluis提醒我the atomic group!为了优化,它非常适合这种情况(如果必须回溯,这种模式永远不会匹配。)
我还投入了一个额外的[^&]+
组,以避免重复多次负面预测。
或者,可以使用possessive quantifier,它基本上做同样的事情(你的正则表达式引擎可能不支持它):
/<a href="(?:[^&]+|(?!").)*+">/s
正如您所看到的那样稍微更短。