StringSplitOptions.RemoveEmptyEntries 不像宣传的那样工作

本文关键字:工作 RemoveEmptyEntries StringSplitOptions | 更新日期: 2023-09-27 18:35:00

我过去遇到过几次,最终决定找出原因。

StringSplitOptions.RemoveEmptyEntries建议它删除空条目

那么为什么这个测试会失败呢?

var tags = "One, Two, , Three,   Foo Bar, , Day    , ";
var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
    .Select(s => s.Trim());
tagsSplit.ShouldEqual(new string[] {
    "One",
    "Two",
    "Three",
    "Foo Bar",
    "Day"
});

结果:

  Values differ at index [2]
  Expected string length 5 but was 0. Strings differ at index 0.
  Expected: "Three"
  But was:  <string.Empty>

所以它失败了,因为 "Three" ,我们有一个空字符串——这正是StringSplitOptions.RemoveEmptyEntries应该防止的。

StringSplitOptions.RemoveEmptyEntries 不像宣传的那样工作

很可能

是因为您在拆分后更改了字符串。拆分值后修剪值,RemoveEmptyEntries不会认为字符串" "为空。

以下内容将实现您想要的,基本上创建自己的条带空元素:

var tagsSplit = tags.Split(',').
                  Select(tag => tag.Trim()). 
                  Where( tag => !string.IsNullOrEmpty(tag));

相邻的分隔符生成一个包含空的数组元素 字符串 ("(。枚举的值指定 包含空字符串的数组元素是否包含在 返回的数组。

根据定义," "不是空的(它实际上是空格(,因此不会从生成的数组中删除它。

如果使用 .net 框架 4,则可以使用字符串来解决此问题。IsNull或空格方法

var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                .Where(x => !string.IsNullOrWhiteSpace(x))
                .Select(s => s.Trim());

在 .NET 5 中,他们添加了StringSplitOptions.TrimEntries .

由于StringSplitOptions具有[System.Flags]属性,这意味着您可以编写

var tagsSplit = tags.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);

当同时指定RemoveEmptyEntriesTrimEntries时,它会删除空值和仅包含空格的值,同时修剪所有剩余值。

RemoveEmptyEntries 不表示空格。
您的输入字符串包含许多"空格"。您应该注意到"空格"不是空的。在计算机中,空格是一种特殊的ASCII码。所以代码:

var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
    .Select(s => s.Trim());

方法:

  1. 将输入拆分为","并删除空条目,不包括空格。所以你得到了一个包含一些空间元素的数组。
  2. 然后,您可以为每个元素进行修剪。空间元素变为空。

这就是你得到它的原因。

尝试

var tagsSplit = tags.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);

这将按逗号和空格吐出,并消除空字符串。

由于这是一个非常常见的需求,我继续将最流行的答案包装在字符串扩展方法中:

public static IEnumerable<string> Split_RemoveWhiteTokens(this string s, params char[] separator)
{
    return s.Split(separator).
          Select(tag => tag.Trim()).
          Where(tag => !string.IsNullOrEmpty(tag));
}

要像其他示例一样拆分 '",",请使用如下:

var result = yourString.Split_RemoveWhiteTokens(',')

请注意,返回类型是 IEnumerable,因此可以直接对返回结果执行其他 LINQ 查询。 叫。ToList(( 如果要将结果转换为列表。

我还搜索了一种在拆分期间排除空格条目的干净方法,但由于所有选项似乎都是某种解决方法,因此我选择在循环数组时排除它们。

string[] tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string tag in tagsSplit.Where(t => !string.IsNullOrWhiteSpace(t))) { }

我认为这看起来更干净,并且 - 作为奖励 - .Split(...).ToArray()可能会被省略。当然,仅当您可以在拆分后循环并且不必存储条目以供以后使用时,它才是一个选项。

EmptyEntries 它的意思是两个分隔符直接相邻,中间没有任何东西。如果不使用此选项,它将打印一个空行来表示此分隔。如果您使用"RemoveEmptyEntryries"选项,它将不会显示分隔符,除非分隔符之间确实存在某些内容。空格计为分隔符之间的内容。如果您尝试过:

One, Two,, Three,

您应该发现RemoveEmptyEntries消除了两个逗号之间的分隔,直接从 2 到 3。

var tagsSplit = tags.Split(',')
                    .Where(str => str != String.IsNullOrWhiteSpace(str))
                    .Select(s => s.Trim());