Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么这个正则表达式是贪婪的?_C#_Regex_Non Greedy - Fatal编程技术网

C# 为什么这个正则表达式是贪婪的?

C# 为什么这个正则表达式是贪婪的?,c#,regex,non-greedy,C#,Regex,Non Greedy,我正在尝试提取“”中包含/thumb/的所有链接。实际上我只需要使用图片src。我不知道图片是否会以jpg结尾,或者是否会有区分大小写的问题,等等。我真的只关心完整的链接 m = Regex.Match(page, @"""(.+?/thumbs/.+?)"""); //... var thumbUrl = m.Groups[1].Value; 我的完整代码 var page = DownloadWebPage(url); var reg = new Regex(@"Eleme

我正在尝试提取“”中包含/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看起来像


中心\“>…大量文本,没有/thumbs/…src=\”

问题在于?也会消耗“s”,因此它会在src属性之外继续匹配。请改用此选项:

m = Regex.Match(page, @"""([^""]+/thumbs/[^""]+)""");

Nongreedy正则表达式可能会很慢,因为引擎必须执行大量回溯

这一个只使用贪婪表达式:

@"""([^""]*/thumbs/[^""]*)"""
<>而不是匹配最少的任何东西,它匹配尽可能多的非双引号。

如果你正在解析(x)html,考虑使用适当的解析器。


请参阅:有关如何执行此操作的一些C#示例。

通常,当使用正则表达式时,您使用静态字段并指定
RegexOptions。已编译的
选项:

static Regex template = new Regex(@"""(.+?/thumbs/.+?)""", RegexOptions.Compiled | RegexOptions.Multiline)
不情愿(不贪婪)的方式quantifier的作用是,一旦它开始匹配,它会在第一次机会时停止。您要做的是匹配满足您的条件的最小文本量,这不是一回事;您仍然必须确保它不会在您希望匹配之前开始匹配。正如其他人所建议的,您可以通过替换
+? 在正则表达式中使用与引号不匹配的内容,如
[^”“]+

但这仍然会给您带来性能问题。在您的示例中,正则表达式在
中心>
中看到引号时开始匹配;当它到达
src=“
(假设您已将
+?
更改为
[^”“]+
)处的引号时,它将中止匹配的移动尝试。从
src=“
中的引号开始的下一次尝试将成功。所以你现在得到了正确的结果,但是你仍然在第一次失败的比赛尝试上浪费了很多时间

编写快速正则表达式的关键是确保,如果匹配尝试失败,它会尽快失败。例如,我认为可以安全地假设您不希望在
/thumbs/
之间有任何尖括号,因此将它们添加到您不希望匹配的字符集中:
[^”“]+
。现在,从
中心“>
中的引号开始的任何匹配尝试都将在下一个位置中止

您还可以做其他事情来进一步优化正则表达式,包括原子组和负lookahead,但这可能会很快满足您的需要:

@"""([^""<>]+/thumbs/[^""<>]+)"""
@”“([^”“]+/thumbs/[^”“]+)”

FYI,“多行”选项对您没有任何帮助。如果希望点与行分隔符匹配,则应使用
Singleline
。一定数量的正则表达式对象会自动缓存,因此在字段中存储一个对象不一定会对性能产生任何影响。而且,
编译的
正则表达式可能更快,但创建它们的成本更高;您是否应该使用该选项取决于您如何使用正则表达式。