web-dev-qa-db-ja.com

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が防ぐべきものです。

26
Ben Foster

おそらく、分割後に文字列を変更したためです。値を分割した後にトリムします。RemoveEmptyEntriesは文字列" "を空と見なしません。

以下はあなたが望むものを達成するでしょう、基本的にあなた自身のストリップの空の要素を作成します:

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

隣接する区切り文字は、空の文字列( "")を含む配列要素を生成します。 StringSplitOptions列挙の値は、空の文字列を含む配列要素が返される配列に含まれるかどうかを指定します。

" "定義によりは空ではない(実際にはwhitespace)であるため、結果の配列から削除されません。

.net framework 4を使用している場合は、 string.IsNullOrWhitespace method を使用して回避できます。

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

RemoveEmptyEntriesはスペースを意味しません。
入力文字列に多くの「スペース」が含まれています。 「スペース」は空ではないことに注意してください。コンピューターでは、スペースは特別なASCIIコードです。コードは次のとおりです。

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

手段:

  1. 入力を '、'で分割し、スペースを含めずに空のエントリを削除します。あなたはいくつかのスペース要素を持つ配列を得ました。
  2. 次に、各要素に対してトリムを行います。スペース要素は空になります。

それがあなたがそれを得た理由です。

7
Coofucoo

試して

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

これにより、コンマとスペースで吐き出され、空の文字列が削除されます。

ホワイトスペースエントリを除外するクリーンな方法も検索しました() Splitですが、すべてのオプションが何らかの回避策のように思えたので、配列をループするときに除外することを選択しました。

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

私はこれがきれいに見えると思います-ボーナスとして-.Split(...).ToArray()は省略されるかもしれません。もちろん、分割直後にループでき、後で使用するためにエントリを保存する必要がない場合にのみ、オプションです。

1
Teodor Tite

これは非常に一般的なニーズであるため、先に進み、最も一般的な答えを文字列拡張メソッドでラップしました。

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()を呼び出します。

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