String.Contains和String.LastIndexOf C#返回不同的结果

本文关键字:String 结果 Contains LastIndexOf 返回 | 更新日期: 2023-09-27 18:20:12

我在String.Contains返回true而String.LastIndexOf返回-1时遇到了这个问题。有人能向我解释一下发生了什么事吗?我使用的是.NET 4.5。

    static void Main(string[] args)
    {
        String wikiPageUrl = @"http://it.wikipedia.org/wiki/ʿAbd_Allāh_al-Sallāl";
        if (wikiPageUrl.Contains("wikipedia.org/wiki/"))
        {
            int i = wikiPageUrl.LastIndexOf("wikipedia.org/wiki/");
            Console.WriteLine(i);
        }
    }

String.Contains和String.LastIndexOf C#返回不同的结果

虽然@sa_ddam213的答案肯定解决了这个问题,但它可能有助于准确了解这个特定字符串的情况。

如果你用其他"特殊角色"来尝试这个例子,问题就不会显现出来。例如,以下字符串按预期工作:

string url1 = @"http://it.wikipedia.org/wiki/»Abd_Allāh_al-Sallāl";
Console.WriteLine(url1.LastIndexOf("it.wikipedia.org/wiki/")); // 7
string url2 = @"http://it.wikipedia.org/wiki/~Abd_Allāh_al-Sallāl";
Console.WriteLine(url2.LastIndexOf("it.wikipedia.org/wiki/")); // 7

有问题的字符"ʿ"被称为间距修饰符字母1。间距修饰符字母并不独立,而是修改字符串中前一个字符,在本例中为"/"。另一种说法是,渲染时不会占用自己的空间。

在没有StringComparison参数的情况下调用LastIndexOf时,会使用当前区域性比较字符串。

当以区分区域性的方式比较字符串时,"/"answers"ʿ"字符不会被视为两个不同的字符——它们被处理为一个字符,与传递给LastIndexOf的参数不匹配。

当您传入StringComparison.OrdinalLastIndexOf时,由于顺序比较的性质,字符将被视为不同的字符。

另一种方法是使用CompareInfo.LastIndexOf并提供CompareOptions.IgnoreNonSpace选项:

Console.WriteLine(
    CultureInfo.CurrentCulture.CompareInfo.LastIndexOf(
        wikiPageUrl, @"it.wikipedia.org/wiki/", CompareOptions.IgnoreNonSpace));
// 7

这里我们说的是,我们不希望在字符串比较中包含组合字符。

顺便说一句,这意味着@Partha的答案和@Noctis的答案之所以有效,是因为该字符被应用于一个没有出现在传递给LastIndexOf的搜索字符串中的字符。

Contains方法形成对比,后者默认情况下执行Ordinal(区分大小写,区分中的区域性)比较。这解释了为什么Contains返回trueLastIndexOf返回false

要了解如何在.NET框架中操作字符串的精彩概述,请查看本文。


1:这与组合字符不同吗?还是一种组合字符?如果有人能帮我清理一下,我将不胜感激。

尝试使用StringComparison.Ordinal

这将通过评估每个string中相应chars的数值来比较string,这应该与该示例中的特殊chars string 一起使用

 string wikiPageUrl = @"http://it.wikipedia.org/wiki/ʿAbd_Allāh_al-Sallāl";
 int i = wikiPageUrl.LastIndexOf("http://it.wikipedia.org/wiki/", StringComparison.Ordinal);

//返回0;

问题是C#lastindexof从后面看。

CCD_ 20后面跟有CCD_。因此,要么在wiki/之后删除',要么在那里也有一个@

以下语法适用于(任何人)

string wikiPageUrl = @"http://it.wikipedia.org/wiki/Abd_Allāh_al-Sallāl";
string wikiPageUrl = @"http://it.wikipedia.org/wiki/@ʿAbd_Allāh_al-Sallāl";
int i = wikiPageUrl.LastIndexOf("wikipedia.org/wiki");

所有3个作品

如果您想要此问题的通用解决方案,请在执行任何操作之前,将字符串中的'替换为@'

'字符将其抛出。

当您以'':的形式逃离'时,这应该会起作用

wikiPageUrl = @"http://it.wikipedia.org/wiki/''Abd_Allāh_al-Sallāl";
if (wikiPageUrl.Contains("wikipedia.org/wiki/"))
{
    "contains".Dump();
  int i = wikiPageUrl.LastIndexOf("wikipedia.org/wiki/");
  Console.WriteLine(i);
}

弄清楚你想做什么(移除',逃离它,或者深入挖掘:)。