我正在尝试提取“/”中包含/ thumb /的所有链接。其实我只需要使用图像src。我不知道图像是以jpg结尾还是会出现区分大小写等问题。我真的只关心完整的链接。
m = Regex.Match(page, @"""(.+?/thumbs/.+?)""");
//...
var thumbUrl = m.Groups[1].Value;
我的完整代码
var page = DownloadWebPage(url);
var reg = new Regex(@"Elements\s+\((.*)\)", RegexOptions.Multiline);
var m = reg.Match(page);
var szEleCount= m.Groups[1].Value;
int eleCount = int.Parse(szEleCount);
m = Regex.Match(page, @"""(.+?/thumbs/.+?)""");
while (m.Success)
{
var thumbUrl = m.Groups[1].Value;
//i break here to see a problem
m = m.NextMatch();
}
thumbUrl看起来像
center \“> ...很多文字,没有/ thumbs / ... src = \”http://images.fdhkdhfkd.com/thumbs/dfljdkl/22350.jpg
答案 0 :(得分:4)
Nongreedy正则表达式可能很慢,因为引擎必须进行大量的回溯。
这个只使用贪婪的表达式:
@"""([^""]*/thumbs/[^""]*)"""
不是匹配最少量的东西,而是匹配尽可能多的非双引号。
答案 1 :(得分:3)
如果要解析(X)HTML,请考虑使用正确的解析器。
有关如何执行此操作的一些C#示例,请参阅:What is the best way to parse html in C#?。
答案 2 :(得分:3)
一个不情愿(非贪婪)量词的工作方式是,一旦它开始匹配,它就会在第一次机会停止。你要做的是匹配符合你标准的最小文本量,这不是一回事;你仍然需要确保它没有开始匹配才能得到它。正如其他人所建议的那样,您可以将正则表达式中的.+?
替换为与引号不匹配的内容,例如[^""]+
。
但这仍然会给您带来性能问题。在您的示例中,正则表达式在center">
中看到引号时开始匹配;当它达到src="
的引用时(假设您已将.+?
更改为[^""]+
),它将中止该匹配尝试继续前进。从src="
中的引用开始的下一次尝试将成功。所以你现在得到了正确的结果,但你仍然在第一次失败的比赛尝试上浪费了很多时间。
编写快速正则表达式的关键是确保如果匹配尝试失败,它将尽快失败。例如,我认为可以安全地假设您不希望在"
和/thumbs/
之间使用任何尖括号,因此将它们添加到您不想匹配的字符集中:{{1 }}。现在,从[^""<>]+
中的引号开始的任何匹配尝试都将在下一个位置中止。
您可以采取其他措施来进一步优化正则表达式,包括原子组和负向前瞻,但这可能会根据您的需要尽快:
center">
答案 3 :(得分:1)
问题在于。+?也消耗“s,所以它继续在src属性之外匹配。请改用:
m = Regex.Match(page, @"""([^""]+/thumbs/[^""]+)""");
答案 4 :(得分:0)
通常当你有正则表达式时,你使用静态字段并指定RegexOptions.Compiled
选项:
static Regex template = new Regex(@"""(.+?/thumbs/.+?)""", RegexOptions.Compiled | RegexOptions.Multiline)