IndexOf C#出错

时间:2013-03-19 13:02:29

标签: c# .net

我显然在这里遗漏了一些东西..

我正在编写一个函数,它返回由特定字符串分隔的子字符串数。 这是一个相当简单的功能 -

public static FuncError DCount(String v1, String v2, ref Int32 result) {
        result = 0;
        if (String.IsNullOrEmpty(v1)) {
            return null;
        }
        if (String.IsNullOrEmpty(v2)) {
            return null;
        }

        int ct = 1;
        int ix = 0;
        int nix = 0;

        do {
            nix = v1.IndexOf(v2, ix);
            if (nix >= 0) {
                ct++;

                System.Diagnostics.Debug.Print(
string.Format("{0} found at {1} count={2} result = {3}",
v2, nix, ct, v1.Substring(nix,1)));
                ix = nix + v2.Length;
            }
        } while (nix >= 0);
        result = ct;
        return null;
    }

当我使用在特定情况下用作分隔符的特殊字符进行调用时,问题就出现了。它返回了许多误报。从Debug.Print开始,第一个和最后一个参数应始终相同。

þ found at 105 count=2 result = t
þ found at 136 count=3 result = t
þ found at 152 count=4 result = þ
þ found at 249 count=5 result = t
þ found at 265 count=6 result = t
þ found at 287 count=7 result = t
þ found at 317 count=8 result = t
þ found at 333 count=9 result = þ
þ found at 443 count=10 result = þ
þ found at 553 count=11 result = þ
þ found at 663 count=12 result = þ
þ found at 773 count=13 result = þ
þ found at 883 count=14 result = þ
þ found at 993 count=15 result = þ

如果我将pass作为char传递它可以正常工作。 如果我使用split作为分隔符拆分字符串,则返回正确数量的元素。 对于错误识别的't',结果中还有其他't'未被拾取,因此它不是字符转换问题。

困惑......

由于

3 个答案:

答案 0 :(得分:5)

这里的问题是不同文化如何代表角色,在某些情况下将它们结合起来。

您要搜索的信件Thorn显然可以用th字母表示。

LINQPad中尝试此代码:

void Main()
{
    string x = "uma thurman";
    x.IndexOf("þ").Dump();
}

它将输出4

(请注意,我在挪威的某台机器上运行此程序,它可能会或可能不会对结果产生影响)

与双S - ß的德语字母相同的“问题”可以在两个s一起的单词中找到,在某些文化中

答案 1 :(得分:2)

您可以使用StringComparison.Ordinal来获取与文化无关的字符串匹配。

使用Lasse V. Karlsen的example

string x = "uma thurman";
x.IndexOf("þ", StringComparison.Ordinal).Dump();

将导致-1

有关详细信息,请参阅Best Practices for Using Strings in the .NET Framework

答案 2 :(得分:0)

您使用的是an overload of IndexOf

  

使用当前文化执行单词(区分大小写和文化敏感)搜索

因此,结果取决于您的线程的CurrentCulture。大多数文化认为letter thorn等同于th。见Lasse的回答。

例如,被称为Þórr的古老的挪威神经常用英语书写Thor,首字母在“星期四”(Thor的一天)中被称为“Th”。

要解决您的问题,请将v1.IndexOf(v2, ix)更改为:

v1.IndexOf(v2, ix, StringComparison.Ordinal)

请参阅the doc on that overload

序数比较以天真的方式逐个比较char值,只需比较它们的数值。相比之下,依赖于文化的比较会对重音字母的不同表示以及文化认为等同的不同字母进行大量的标准化。这在排序规则中也非常重要,例如通过序数比较,字符串"naïve"在排序后的 字符串"nasty"之后出现 (因为System.Char'ï'的数值高于's')。