StringSplitOptions.RemoveEmptyEntries не работает, как рекламируется
Я сталкивался с этим несколько раз в прошлом и, наконец, решил выяснить, почему.
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
должно предотвратить.
Ответы
Ответ 1
Скорее всего, потому что вы изменили строку после разделения. Вы RemoveEmptyEntries
значения после их разделения, RemoveEmptyEntries
не считает строку " "
пустой.
Следующее будет достигать того, что вы хотите, в основном создавая собственные пустые пустые элементы:
var tagsSplit = tags.Split(',').
Select(tag => tag.Trim()).
Where( tag => !string.IsNullOrEmpty(tag));
Ответ 2
Смежные разделители дают элемент массива, содержащий пустой string (""). Значения перечисления StringSplitOptions указывают содержит ли элемент массива, который содержит пустую строку, в возвращенный массив.
" "
по определению не пуст (на самом деле это пробел), поэтому он не удаляется из результирующего массива.
Если вы используете .net framework 4, вы можете обойти это, используя string.IsNullOrWhitespace:
var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Where(x => !string.IsNullOrWhiteSpace(x))
.Select(s => s.Trim());
Ответ 3
RemoveEmptyEntries не означает пробел.
Ваша строка ввода включает в себя множество "пробелов". Вы должны заметить, что "пространство" не пустое. В компьютере пространство представляет собой специальный код ASCII. поэтому код:
var tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Trim());
означает:
- Разделите ввод на ',' и удалите пустую запись, а не укажите пробел. Так
вы получили массив с некоторыми элементами пространства.
- Затем вы выполняете обрезку для каждого из элементов. Элементы пространства становятся пустыми.
Вот почему ты это понял.
Ответ 4
Try
var tagsSplit = tags.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
Это будет запятнать запятой и пробелом и устранить пустые строки.
Ответ 5
Я также искал чистый способ исключить пробельные записи во время разделения, но поскольку все параметры выглядели как-то вроде обходных решений, я решил исключить их при переходе по массиву.
string[] tagsSplit = tags.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string tag in tagsSplit.Where(t => !string.IsNullOrWhiteSpace(t))) { }
Я думаю, что это выглядит чище и - в качестве бонуса - .Split(...).ToArray()
может быть пропущено.
Конечно, это вариант, когда вы можете зацикливать сразу после разделения и не хранить записи для последующего использования.
Ответ 6
var tagsSplit = tags.Split(',')
.Where(str => str != String.IsNullOrWhiteSpace(str))
.Select(s => s.Trim());
Ответ 7
Поскольку это очень распространенная необходимость, я пошел дальше и обернул самый популярный ответ в метод расширения строки:
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(), если вы хотите привести результат к списку.
Ответ 8
Value.Split(новый char [] {'/'}, StringSplitOptions.RemoveEmptyEntries);
Это будет разбито на Slash. Он работает отлично!