【问题标题】:Getting an extra blank item when splitting a string拆分字符串时获得额外的空白项
【发布时间】:2015-09-20 04:18:11
【问题描述】:

我用“\0”分隔符分割一个字符串,我得到一个额外的空白尾随项,我不知道为什么。应该有 5 个参数,每个参数都以“\0”结尾。这是字符串:

在此处启动\0\0消息。\01返回\0\0

这是我的代码:

var paramList = new List<string>(parameters.Split("\0".ToCharArray()));

这就是我得到的原因:

[0] = "Splash"
[1] = ""
[2] = "Message here."
[3] = "1Back"
[4] = ""
[5] = ""

拆分时无法删除空参数,因为它们的位置很重要。

字符串有 5 个参数/分隔符,但返回 6 个元素。位置很重要,因为 [0] 始终是标题,[1] 始终是副标题,[2] 消息,[3] 按钮 1,[4] 按钮 2。

忽略最后一项对我来说很容易,但我想知道它为什么存在以及我做错了什么。

【问题讨论】:

  • 5 个分隔符意味着将有 6 个元素。如果你有一个只有一个分隔符的字符串,你会得到 2 个元素。如果你只想要 5 个元素,那么去掉最后一个分隔符,就没有必要了。

标签: c#


【解决方案1】:

使用StringSplitOptions.RemoveEmptyEntries 删除空条目

替换

var paramList = new List<string>(parameters.Split("\0".ToCharArray()));

var paramList = new List<string>(parameters.Split("\0".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));

要仅跳过最后一个空项目,请使用

var parameters = "Splash\0\0Message here.\01Back\0\0";
var splitted = parameters.Split("\0".ToCharArray());
var paramList = new List<string>(splitted.Take(splitted.Length - 1));

【讨论】:

    【解决方案2】:

    你没有做错任何事。没有额外的结果。它工作正常。

    Split 不是用于查找由给定分隔符终止的子字符串,而是在给定分隔符处拆分子字符串。

    就像切一条面包一样,如果您切 1 次,您最终会得到 2 片。 如果你进行两次切割,你最终会得到 3 块。 如果您进行 3 次切割,您最终会得到 4 件。 等等……

    您有 5 个剪切(5 个“\0”分隔符),因此您最终会得到 6 个子字符串。

    如果您不想要最后一个,则只需将其删除。有很多方法可以做到这一点!搜索“从列表中删除最后一个元素”、“从数组中删除最后一个元素”或您首选的容器类型。

    【讨论】:

      【解决方案3】:

      忽略最后一项对我来说很容易,但我想知道它为什么存在以及我做错了什么。

      你没有做错任何事。 Split() 在这种情况下正在做它应该做的事情。

      "1,2".Split(',') -> ["1", "2"]
      ",".Split(',')   -> ["", ""]
      "1,,".Split(',') -> ["1", "", ""]
      

      如果您的 CSV 文件的第一行有 2 个逗号,您会认为该文件有 3 个标题,对吗?如果下一行只包含两个逗号,你会认为有三个值,它们都是空字符串。同样,具有 4 个分隔符的行被认为具有 5 个值,并且(如您的示例中)具有 5 个分隔符的行被认为具有 7 个值..

      在您的情况下,字符串以 '\0' 结尾的事实意味着拆分该字符串将在末尾产生一个最终的空字符串,这正是您所看到的行为。

      如果您希望输入以与拆分字符串相同的值结尾,那很好:只需忽略最后一项,它应该始终为空。

      【讨论】:

        【解决方案4】:

        索引 4 和 5 是“”,因为字符串以两个 NUL 结尾。要删除这些,您可以执行类似的操作

        const char NUL = '\0';
        var paramList = new List<string>(parameters.TrimEnd(NUL).Split(NUL));
        

        我不确定你为什么要把paramList 变成Liststring.Split 返回一个对你来说应该没问题的字符串数组。

        var params = parameters.TrimEnd(NUL).Split(NUL);
        

        【讨论】:

        • 你说得对,我不需要列表,但我不能删除最后两个 \0,它们正在关闭第 4 个参数 1Back 和第 5 个参数,它是一个空字符串
        • Split 不关心字符串是否以拆分字符结尾(关闭)。所以你仍然可以TrimEnd,你会得到一个包含 5 个项目的数组。
        【解决方案5】:

        如果您只想要前五个,请使用Take(5)?...

                string parameters = @"Splash\0\0Message here.\01Back\0\0";
                var paramList = new List<string>(parameters.Split(new string[] { @"\0" }, StringSplitOptions.None).Take(5));
                for(int i = 0; i < paramList.Count; i++)
                {
                    Console.WriteLine(i.ToString() + ": " + paramList[i]);
                }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-21
          • 1970-01-01
          相关资源
          最近更新 更多