C# 将字符串与带有IgnoreCase的正则表达式比较快,还是与字符串的ToLower方法比较快?

C# 将字符串与带有IgnoreCase的正则表达式比较快,还是与字符串的ToLower方法比较快?,c#,regex,C#,Regex,给定如下字符串: string s1 = "Abc"; string s2 = "ABC"; 什么更快: Regex.Match(s1, s2, RegexOptions.IgnoreCase) 或 如果它们相同,或者一个比另一个快,那么什么时候使用一个比另一个好呢?可能第二个更快,但我会避免这两种方法 更好的方法是将该方法与适当的StringComparison参数一起使用: s1.Equals(s2, StringComparison.CurrentCultureIgnoreCase)

给定如下字符串:

string s1 = "Abc";
string s2 = "ABC";
什么更快:

Regex.Match(s1, s2, RegexOptions.IgnoreCase)


如果它们相同,或者一个比另一个快,那么什么时候使用一个比另一个好呢?

可能第二个更快,但我会避免这两种方法

更好的方法是将该方法与适当的
StringComparison
参数一起使用:

s1.Equals(s2, StringComparison.CurrentCultureIgnoreCase)

在线查看它的工作原理:

从理论上讲,比较两个字符串应该更快,众所周知正则表达式相当慢

但是,如果希望在忽略大小写的情况下将字符串s1与正则表达式s2匹配(这与比较两个字符串不同),那么第一个解决方案会更好,因为它应该避免创建另一个字符串


像往常一样,对于这类问题,我会运行一个基准测试并比较两种性能:)

@Mark Byers已经给出了正确的答案

我想强调的是,永远不要使用ToLower进行字符串比较。这是不正确的

s1.Equals(s2, StringComparison.CurrentCultureIgnoreCase) //#1
s1.ToLower() == s2.ToLower() //#2
s1.ToLowerInvariant() == s2.ToLowerInvariant() //#3
(2) 和(3)都是不正确的,当涉及到异国语言和奇怪的字符。土耳其语的“I”就是一个经典的例子

始终使用#1,即使在哈希表中也是如此


(除了非常特殊的情况)

应该注意的是,
Regex.Match(s1,s2,RegexOptions.IgnoreCase)
不是在一般情况下检查不区分大小写的相等性的安全方法。考虑<代码> S2<代码> <代码> > * < <代码>。code>Regex.Match将始终返回true,无论
s1
是什么

比较会更快,但与其转换为小写或大写然后进行比较,不如使用不区分大小写的相等比较。例如:

        s1.Equals(s2, StringComparison.OrdinalIgnoreCase)

下面是对所提出的3种方法的一个小比较:

正则表达式:282ms 托洛尔:67毫秒 等于:34毫秒

publicstaticvoid RunSnippet()
{
字符串s1=“Abc”;
字符串s2=“ABC”;
//预载
比较正则表达式(s1,s2);
比较低(s1,s2);
比较质量(s1、s2);
//正则表达式
Stopwatch swRegex=Stopwatch.StartNew();
对于(int i=0;i<300000;i++)
比较正则表达式(s1,s2);
WriteLine(string.Format(“Regex:{0}ms”,swRegex.elapsedmillesons));
//托洛尔
秒表swToLower=Stopwatch.StartNew();
对于(int i=0;i<300000;i++)
比较低(s1,s2);
WriteLine(string.Format(“ToLower:{0}ms”,swToLower.elapsedmillesons));
//托洛尔
秒表swEquals=Stopwatch.StartNew();
对于(int i=0;i<300000;i++)
比较质量(s1、s2);
WriteLine(string.Format(“等于:{0}ms”,swEquals.elapsedmillesons));
}
私有静态布尔比较正则表达式(字符串s1、字符串s2)
{
返回Regex.IsMatch(s1,s2,RegexOptions.IgnoreCase);
}
专用静态布尔比较低(字符串s1、字符串s2)
{
返回s1.ToLower()==s2.ToLower();
}
专用静态布尔比较单相等(字符串s1、字符串s2)
{
返回s1.Equals(s2,StringComparison.CurrentCultureIgnoreCase);
}

这可能是我见过的最极端的情况。相信我,你永远不会遇到与这个问题相关的情况


不要听那些告诉你不要使用正则表达式的人的话,因为“它们很慢”。写得不好的正则表达式确实会占用资源,但这是编写正则表达式的人的错。设计合理的正则表达式对于人们应用它们的绝大多数任务来说都足够快

普通字符串操作通常比正则表达式快。Regex.Match非常不正确。无论如何,这不是一个可行的解决办法。正则表达式不是字符串-它是正则表达式模式。@fardjad,为什么正则表达式通常较慢?我想+1指出,基准测试是回答这些问题的最佳方式,但我今天没有投票!这不是一个公平的比较。我尝试提前创建Regex对象并将其存储在静态变量中,然后对其调用
IsMatch()
,结果是:
Regex:71ms
ToLower:51ms
Equals:23 ms
。由于
s2
包含实际正则表达式的情况,这也是一个无效的比较。要求将字符串与忽略大小写进行比较。当然,如果你说S1永远不会改变(在这种情况下,你可以编译/保留ReGEXP对象)+1,也可以考虑几个优化,也可以考虑S2是无效正则表达式的情况。
        s1.Equals(s2, StringComparison.OrdinalIgnoreCase)
public static void RunSnippet()
{
    string s1 = "Abc";
    string s2 = "ABC";

    // Preload
    compareUsingRegex(s1, s2);
    compareUsingToLower(s1, s2);
    compareUsingEquals(s1, s2);

    // Regex
    Stopwatch swRegex = Stopwatch.StartNew();
    for (int i = 0; i < 300000; i++) 
        compareUsingRegex(s1, s2);
    Console.WriteLine(string.Format("Regex: {0} ms", swRegex.ElapsedMilliseconds));

    // ToLower
    Stopwatch swToLower = Stopwatch.StartNew();
    for (int i = 0; i < 300000; i++) 
        compareUsingToLower(s1, s2);
    Console.WriteLine(string.Format("ToLower: {0} ms", swToLower.ElapsedMilliseconds));

    // ToLower
    Stopwatch swEquals = Stopwatch.StartNew();
    for (int i = 0; i < 300000; i++) 
        compareUsingEquals(s1, s2);
    Console.WriteLine(string.Format("Equals: {0} ms", swEquals.ElapsedMilliseconds));
}

private static bool compareUsingRegex(string s1, string s2) 
{
    return Regex.IsMatch(s1, s2, RegexOptions.IgnoreCase);
}

private static bool compareUsingToLower(string s1, string s2) 
{
    return s1.ToLower() == s2.ToLower();
}

private static bool compareUsingEquals(string s1, string s2) 
{
    return s1.Equals(s2, StringComparison.CurrentCultureIgnoreCase);
}