【问题标题】:String.Contains and String.LastIndexOf C# return different result?String.Contains 和 String.LastIndexOf C# 返回不同的结果?
【发布时间】:2014-09-02 00:36:20
【问题描述】:

我有这个问题,其中 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);

        }
    }

【问题讨论】:

  • 如果那是直接 C&P,那么它不会编译。如果不是直接 C&P:为什么不呢?
  • 它为我返回 10,正如预期的那样 (demo)。投票结束,因为不可复制。
  • 代码无法编译。我认为您使用的引号是 Unicode 字符。
  • 你打错了:int i = wikiPageUrl.LastIndexOf (( “wikipedia.org/wiki/” );
  • @Dima,引号和缺少的分号怎么办?

标签: c# contains lastindexof


【解决方案1】:

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

如果您尝试使用其他“特殊字符”的示例,则不会出现问题。例如,以下字符串按预期工作:

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

有问题的字符“ʿ”称为spacing modifier letter1。间距修饰符字母不是独立存在的,而是修饰字符串中的 previous 字符,本例中为“/”。另一种说法是它在渲染时不占用自己的空间。

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

当以文化敏感的方式比较字符串时,“/”和“ʿ”字符不会被视为两个不同的字符——它们被处理成一个字符,不匹配 传入LastIndexOf的参数。

当您将StringComparison.Ordinal 传递给LastIndexOf 时,由于序数比较的性质,字符被视为不同。

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

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

这里我们说我们不想组合字符串比较中包含的字符。

作为旁注,这意味着 @Partha's answer@Noctis' answer 仅在将字符应用于未出现在传递给 LastIndexOf 的搜索字符串中的字符时才有效。

将此与Contains 方法进行对比,该方法默认执行Ordinal(区分大小写和区分区域性)比较。这就解释了为什么Contains 返回trueLastIndexOf 返回false

如需了解如何在 .NET 框架中操作字符串,请查看this article


1:这与组合字符不同还是一种组合字符?如果有人能帮我解决这个问题,我将不胜感激。

【讨论】:

    【解决方案2】:

    尝试使用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;

    【讨论】:

      【解决方案3】:

      事情是 C# lastindexof 从后面看。

      wikipedia.org/wiki/ 之后是 ',它作为转义序列。所以要么在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");
      

      全部三部作品

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

      【讨论】:

        【解决方案4】:

        ' 字符把它扔掉了。

        当您将' 转义为\' 时,这应该可以工作:

        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);
        
        }
        

        弄清楚你想做什么(删除',转义它,或者深入挖掘:))。

        【讨论】:

        • 我正在整个 Wikipedia 上运行该作业,并且 wikiPageUrl 列来自我不想预处理的数据库。我已经有一些工作了,但我想知道为什么 Contains 返回“true”而 LastIndexOf 返回“-1”
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-24
        • 1970-01-01
        • 1970-01-01
        • 2020-02-15
        • 1970-01-01
        • 2020-02-17
        • 2011-10-02
        相关资源
        最近更新 更多