Bir String.Split işleminde boşluk belirtmenin en iyi yolu


243

Aşağıdaki gibi boşluk dayalı bir dize bölme:

string myStr = "The quick brown fox jumps over the lazy dog";

char[] whitespace = new char[] { ' ', '\t' };
string[] ssizes = myStr.Split(whitespace);

Bunu yapmak istediğim kodumun her yerinde char [] dizisini tanımlamak çok zor. Karakter dizisinin oluşturulmasını gerektirmeyen daha etkili bir yol var mı (farklı yerlerde kopyalanırsa hataya eğilimli)?


1
bunu yapar: myStr.Split (''); çalışmıyor mu?
woolagaroo

4
Bunu doğru

Ayrıca yinelenen olası kopyalara bakın, ancak bu sonraki yanıtlarda SplitStringOptions vardır. stackoverflow.com/questions/1562981/…
goodeye

Yanıtlar:


469

Sadece ararsanız:

string[] ssize = myStr.Split(null);

veya:

string[] ssize = myStr.Split(new char[0]);

o zaman beyaz boşluğun yarma karakteri olduğu varsayılır. Gönderen string.Split(char[])yöntemin dokümantasyon sayfasından .

Separator parametresi nullkarakter içeriyorsa veya hiç karakter içermiyorsa, boşluk karakterlerinin sınırlayıcı olduğu varsayılır. Beyaz boşluk karakterleri Unicode standardı tarafından tanımlanır trueve Char.IsWhiteSpaceyönteme iletildiklerinde geri döner .

Daima, daima, daima belgeleri okuyun!


2
Boşluğa göre bölmeyle ilgili sorun, onu tekrar bir araya getirmeniz gerektiğinde, hangi boşluk karakterini geri koyacağınızı bilmiyorsunuzdur.
Ross Presser

19
(char[])nullyeni bir nesne oluşturmaktan kaçındığı için biraz daha iyidir. ( Aşırı yüklemelerin nullhiçbiriyle kullanamazsınız options).
Artfunkel

5
@RossPresser: Bir dizeyi bir araya getirmek tamamen farklı bir sorundur, bu yüzden burada bir sorun olduğunu söyleyemem. Ama tek yapmanız gereken ipi tam olarak eskisi gibi bir araya getirmekse, belki de orijinalini saklamak daha iyidir.
stakx - artık

4
Aptalca bir soru, ancak kullanırsanız null, StringSplitOption.RemoveEmptyEntriesvarsayılan olarak yoksayar mı yoksa belirtmeniz mi gerekiyor ?
yu_ominae

2
@RossPresser: String.Split, dizeyi ayırmak için kullanılan karakterleri takip etmek için herhangi bir mekanizma sağlamadığından, gözleminiz uygun değildir: String.Split kullanarak aradığınızı elde edemezsiniz, bu yüzden farklı bir Soru-Cevap gerektirir.
ToolmakerSteve

207

Evet, burada bir cevap daha gerekiyor!

Şimdiye kadar tüm çözümler kanonik girdinin oldukça sınırlı alanını ele almak için: elemanlar arasında tek bir boşluk karakteri (en azından problemden bahsetmek için @cherno'ya şapka ucu olsa da). Ancak, en belirsiz senaryolar dışında, tüm bunların bölünmesinin aynı sonuçları vermesi gerektiğini söylüyorum :

string myStrA = "The quick brown fox jumps over the lazy dog";
string myStrB = "The  quick  brown  fox  jumps  over  the  lazy  dog";
string myStrC = "The quick brown fox      jumps over the lazy dog";
string myStrD = "   The quick brown fox jumps over the lazy dog";

String.Split(buradaki diğer cevaplar boyunca gösterilen lezzetlerin herhangi birinde) RemoveEmptyEntriesseçeneği bunlardan herhangi birine eklemediğiniz sürece iyi çalışmaz :

myStr.Split(new char[0], StringSplitOptions.RemoveEmptyEntries)
myStr.Split(new char[] {' ','\t'}, StringSplitOptions.RemoveEmptyEntries)

Şekilde görüldüğü gibi, seçeneği atlamak, kullandığınızda dört girişin her birinden dört farklı sonuç (A, B, C ve D etiketli) ile sonuçlanır RemoveEmptyEntries:

String.Split vs Regex.Split

Tabii ki, seçenekleri kullanmaktan hoşlanmıyorsanız, regex alternatifini kullanın :-)

Regex.Split(myStr, @"\s+").Where(s => s != string.Empty)

4
Bence, @RossPresser, bu benim niteleyici tarafından "en belirsiz senaryolar dışında hepsi altında" olduğunu çünkü öğeleri yeniden birleştirmek istesem bile birden fazla boşluk umurumda bir davaya sahip olmak için zor olurdu. Kanonik bir form istiyorum - her biri arasında bir boşluk. Bu yüzden saygıyla katılmıyorum - "genellikle yanlış" yerine "nadiren yanlış" olurdu.
Michael Sorens

1
CapitalizeEveryWord("This is line one.\n \nThis is line three.")
Ross Presser

3
Bunun gerçekten belirsiz olduğunu düşünüyorsanız, sanırım katılmamaya karar vermeliyiz, ancak bu işlevi yazılımımın dışında bırakırsam işimi kaybederdim. Kullanıcılar, içeriklerinden istedikleri gibi görünmelerini ister.
Ross Presser

4
Çok daha eksiksiz olduğu için bu kabul edilmiş bir cevap olmalıdır.
Dennis

1
Neden .Where(s => s != string.Empty)Regex'e eklediğini merak ediyorum . Belirttiğiniz yana \s+(boşluklar herhangi bir sayıda) arasında hiçbir boş öğe olamaz.
Jack Miller

44

Belgelere göre :

Separator parametresi null olursa veya karakter içermiyorsa, boşluk karakterlerinin sınırlayıcı olduğu varsayılır. Beyaz boşluk karakterleri Unicode standardı tarafından tanımlanır ve Char.IsWhiteSpace yöntemine iletildiklerinde true döndürür.

Yani sadece ara myStr.Split();Hiçbir şey geçmeye gerek yok çünkü ayırıcı bir paramsdizi.


11

Neden kullanmıyorsun ?:

string[] ssizes = myStr.Split(' ', '\t');

2
İki karakter alan Split aşırı yüklemesi yoktur.
takrl

1
@takrl: Buraya bak genel dize [] Böl (params char [] ayırıcı) .NET v2
Renatas M.

Evet, bu bir karakter dizisi gerektirir. Kod snippet'iniz iki tek karakter geçirir.
takrl

15
@takrl: params anahtar kelimesinin ne olduğunu biliyor musunuz ???
Renatas M.

Çok güzel, bunun için +1. Muhtemelen aşağı inen kişi de bilmiyordu.
takrl

3

Bitişik beyaz boşluğun, kullanıldığında bile tek bir ayırıcı olarak işlem görmeyeceğini unutmayın String.Split(null). Jetonlarınızdan herhangi biri birden çok boşluk veya sekmeyle ayrılırsa dizinizde boş dizeler döndürürsünüz.

Belgelerden:

Her ayırıcı eleman ayrı bir ayırıcı karakter tanımlar. İki sınırlayıcı bitişikse veya bu örneğin başında veya sonunda bir sınırlayıcı bulunursa, karşılık gelen dizi öğesi Boş içerir.


2

Bu yüzden kopyalayıp yapıştırmayın! Bölme işleminizi yapmak ve yeniden kullanmak için bir işlev ayıklayın.

public static string[] SplitWhitespace (string input)
{
    char[] whitespace = new char[] { ' ', '\t' };
    return input.Split(whitespace);
}

Kodun yeniden kullanımı senin arkadaşın.



1

kullanabilirsiniz

var FirstString = YourString.Split (). İlk ();

dizeyi bölmek.


0

Satır içi yapamaz mısın?

var sizes = subject.Split(new char[] { ' ', '\t' });

Aksi takdirde, bu şeyi sık sık yaparsanız, her zaman sabit veya o karakter dizisini içeren bir şey oluşturabilirsiniz.

Diğerleri belirttiği gibi belgelere göre de kullanabilirsiniz nullveya boş bir dizi. Bunu yaptığınızda boşluk karakterleri otomatik olarak kullanılacaktır.

var sizes = subject.Split(null);

0

Aynı kodu tekrarlamak sorunsa, String sınıfına bölme mantığını kapsayan bir uzantı yöntemi yazın.


1
Bu soruya gerçekten cevap vermiyor, üzgünüm.
p.campbell

s. campbell: Evet öyle: OP, karakter dizisini her yere kopyalamayı gerektirmeyen bir çözüm istedi. Açık bir çözüm, görevi yerine getirmek için bir işlev oluşturmaktır. Bu yanıt, böyle bir işlevin bir uzantı yöntemi olabileceğine işaret eder. (Yanıt, bunu yapmak için kod gösterilerek geliştirilebilir ...)
ToolmakerSteve

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.