【问题标题】:string IndexOf and Replace字符串 IndexOf 和替换
【发布时间】:2011-02-07 15:39:37
【问题描述】:

我今天刚刚遇到这个问题,想知道是否有人知道为什么这个测试可能会失败(取决于文化)。目的是检查测试文本是否包含两个相邻的空格,根据string.IndexOf(即使我告诉字符串替换所有相邻的两个空格)。经过一些测试,似乎\xAD 以某种方式导致了这个问题。

public class ReplaceIndexOfSymmetryTest
{
    [Test]
    public void IndexOfShouldNotFindReplacedString()
    {
        string testText = "\x61\x20\xAD\x20\x62";
        const string TWO_SPACES = "  ";
        const string ONE_SPACE = " ";
        string result = testText.Replace(TWO_SPACES, ONE_SPACE);
        Assert.IsTrue(result.IndexOf(TWO_SPACES) < 0);
    }
}

【问题讨论】:

  • 我不确定这是否会成为您的问题,但如果您在此测试中彼此相邻有 3 个空格,那么您最终会在结束时彼此相邻 2它。
  • 我的测试成功了。您确定您发布的代码与您正在测试的代码相同吗?
  • 问题是 IndexOf 使用特定于文化的搜索,而 Replace 使用序数搜索。 @Chris:关键是它应该失败。
  • @Jaroslav:我认为你的意思是“它可能会失败”——取决于当前的文化?
  • @Chris:更像是“他预计它会失败”。无论如何,这种毫无意义的讨论 - 我已经指定它是特定于文化的。

标签: c# .net replace


【解决方案1】:

是的,我以前也遇到过同样的事情(尽管字符不同)。基本上IndexOf 在查找匹配项时会考虑“特殊”Unicode 字符的各个方面,而Replace 只是将字符串视为代码点序列。

来自IndexOf docs

此方法使用当前区域性执行单词(区分大小写和区域性)搜索。搜索从该实例的第一个字符位置开始,一直持续到最后一个字符位置。

...来自Replace:

此方法执行序数(区分大小写和不区分区域性)搜索以查找 oldValue。

您可以使用IndexOf 的重载,它接受StringComparison,并强制它执行序数比较。

【讨论】:

  • 检查反射器后,我发现它默认使用 StringComparison.CurrentCulture。我应该已经学会避免参数中的默认值。谢谢乔恩。
  • The documentation for String.IndexOf in the .Net Micro Framework 还声明搜索“区分大小写和区域性”。但遗憾的是,netmf 中没有 System.StringComparison,也没有 String.IndexOf 可以接受它们。
【解决方案2】:

就像 Jon 说的,使用 StringComparison.Ordinal 来做对。

Assert.IsTrue(result.IndexOf(TWO_SPACES, StringComparison.Ordinal) < 0);

【讨论】:

    猜你喜欢
    • 2012-08-29
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 2021-09-12
    相关资源
    最近更新 更多