Bir Java Dizesinin tüm boşluklar olmadığını nasıl kontrol ederim?


132

Java dizgesinin veya karakter dizisinin yalnızca Java kullanarak boşluklardan oluşmadığını kontrol etmek istiyorum.

Javascript dışında bu çok benzer bir sorudur:
Dizenin yalnızca boşluk değil, karakter ve boşluk içerip içermediğini nasıl kontrol edebilirim?

DÜZENLE : Alfasayısal karakterlerle ilgili kısmı kaldırdım, bu yüzden daha mantıklı.


3
Boşluğun birçok farklı tanımı olduğunu unutmayın: spreadsheets.google.com/pub?key=pd8dAQyHbdewRsnE5x5GzKQ Hangisini istiyorsunuz? Ya da "alfanümerik bir karaktere sahip" diyorsunuz, bu tamamen farklı bir şey. Lütfen açıkla.
Kevin Bourrillion

Karışıklık için özür dilerim ... tüm boşluk karakterleri anahtar değildir - temelde tüm boşluk karakterleri varsa, onu hariç tutmak istiyorum, çünkü içeriği yoktur.
Ankur

1
JDK / 11 ile aynı şekildeString.isBlank API'den yararlanabilirsiniz.
Naman

Yanıtlar:


224

Aklıma gelen en kısa çözüm:

if (string.trim().length() > 0) ...

Bu yalnızca (olmayan) beyaz boşluğu kontrol eder. Belirli karakter sınıflarını kontrol etmek istiyorsanız, match()mighty'i aşağıdaki gibi bir regexp ile kullanmanız gerekir :

if (string.matches(".*\\w.*")) ...

... en az bir (ASCII) alfasayısal karakteri kontrol eder.


9
FWIW: İlk çözümün oldukça hızlı olmasını bekliyorum.
Stephen C

2
@Stephen C: Kesinlikle! Ancak @Uri'nin de belirttiği gibi, sorunun belirsizliği nedeniyle iki farklı sorunu çözmek zorunda kalıyorum :) Ayrıca nadiren kullanıyorum matches(): performans için genellikle Patternin a final static. Aynı kod sık çalışıyorsa karşılığını verir.
Carl Smotricz

3
@Andreas_D: Heh, siparişlerimi aldım! OP bir dizi veya karakter dizisini kontrol etmek istediğini söyledi, boşlar hakkında hiçbir şey söylemedi! :) * sözleşmedeki ince yazıları kontrol eder * " nulldize değildir!"
Carl Smotricz

1
Ayrıca, "\\ w", AZ, az, 0-9 ve alt çizgi olarak tanımlanan "kelime karakterlerine" atıfta bulunduğundan, beyaz olmayan tüm karakterlerden ziyade, boşluk olmayan karakterlerin sınırlı bir alt kümesiyle eşleşir.
Rob Raisch

2
Your_string.trim (). İsEmpty () kullandım ve işi benim için yaptım
Neri

59

Apache Commons Lang kütüphanesini kullanırdım. Her tür String işlemi için yararlı olan StringUtils adlı bir sınıfı vardır. Bir Dize'nin tüm boşluklar olmadığını kontrol etmek için aşağıdakileri kullanabilirsiniz:

StringUtils.isBlank(<your string>)

İşte başvuru: StringUtils.isBlank


8
Seçilen cevaba kıyasla bu çözümü tercih ederim. Bu aynı zamanda string == null olup olmadığını da kontrol edecek
Richard

Bu artık yanlıştır. StringUtils.isEmpty"" geçerseniz şimdi yanlış döndürür.
James Spence

53

Carl Smotricz'in bahsettiğinden biraz daha kısa:

!string.trim().isEmpty();

10
Siz genç kırbaçcılar ve yeni çıkmış Java-1.6 sonrası hileleriniz! Cidden, şirketimdeki en az bir proje hala Java 1.4'te çalışıyor (iç çekiş).
Carl Smotricz

Daha kısa? Evet. Şahsen, daha ayrıntılı kodlama stilini seviyorum
Michel


9

Java 11 kullanıyorsanız , yeniisBlank dize yöntemi kullanışlı olacaktır:

!s.isBlank();

Eğer kullanıyorsanız , Java 8, 9 veya 10 , bir dize boşluk sadece olmadığını kontrol etmek için basit akışı inşa edebileceğini:

!s.chars().allMatch(Character::isWhitespace));

Apache Commons Lang gibi herhangi bir üçüncü taraf kitaplığı gerektirmemesine ek olarak, bu çözümler, diğer birçok yanıtta önerildiği ' 'gibi yalnızca düz boşlukları değil, herhangi bir beyaz boşluk karakterini işleme avantajına sahiptir trim. Desteklenen tüm beyaz boşluk türlerinin kapsamlı bir listesi için Javadocs'a başvurabilirsiniz . Her iki durumda da boş dizelerin kapsandığına dikkat edin.


5
if(target.matches("\\S")) 
    // then string contains at least one non-whitespace character

Ters eğik çizgi büyük harf S'nin kullanımına dikkat edin, yani "boşluk olmayan karakter"

Bunun en basit (ve belki de en hızlı?) Çözüm olduğuna bahse girerim.


2
Bir deneyelim: String year="1995"; year.matches("\\S"); will return falseYani bu doğru çözüm değil. : |
Nhat Dinh

6
Nhat, haklısın ama nedenini açıklayamıyorum. Java belgelerine göre, String.matches belirli bir dizenin bir normal ifadeyle eşleşip eşleşmediğini kontrol eder. Küçük bir deney, bu işlevin YALNIZCA sağlanan normal ifadenin TÜM dizeyle eşleştiğinde eşleştiği için bunun tamamen doğru olmadığını göstermektedir! Dolayısıyla, yukarıdaki normal ifadeyi ("\\ S") "^. * \\ S. * $" Olarak değiştirmek, beklendiği gibi çalışacaktır, ancak bu davranış doğru bir şekilde belgelenmemiştir ve dize eşleştirmenin diğer tüm uygulamalarından önemli ölçüde farklı görünmektedir. Normal İfadeler kullanarak.
Rob Raisch

4

Bu cevap, " yani en az bir alfanümerik karaktere sahip olan " yan nota daha fazla odaklanır . Bunun yanı sıra, diğer (önceki) çözüme çok fazla şey katmaz, ancak String'in olması durumunda NPE ile size zarar vermez null.

Biz istiyoruz false(1) 'dir buysa nullveya (2) ler boş veya (3) sadece whitechars içerir s.

public static boolean containsNonWhitespaceChar(String s) {
  return !((s == null) || "".equals(s.trim()));
}

4

Yalnızca beyaz boşlukları kontrol ediyorsanız ve null değerini önemsemiyorsanız, org.apache.commons.lang.StringUtils.isWhitespace (String str),

StringUtils.isWhitespace(String str);

(Dize yalnızca boşluk içerip içermediğini kontrol eder.)

Ayrıca boş değeri (boşluk dahil) kontrol etmek istiyorsanız

StringUtils.isBlank(String str);

isBlank (String), aynı zamanda boş doğrulamayı da işlediği için önerilir!
Sachidananda Naik

2

Java-11 + ile, String.isBlankverilen dizenin tamamen boşluktan oluşup oluşmadığını kontrol etmek için API'yi kullanabilirsiniz -

String str1 = "    ";
System.out.println(str1.isBlank()); // made up of all whitespaces, prints true

String str2 = "    a";
System.out.println(str2.isBlank()); // prints false

Aynı şey için javadoc şudur:

/**
 * Returns {@code true} if the string is empty or contains only
 * {@link Character#isWhitespace(int) white space} codepoints,
 * otherwise {@code false}.
 *
 * @return {@code true} if the string is empty or contains only
 *         {@link Character#isWhitespace(int) white space} codepoints,
 *         otherwise {@code false}
 *
 * @since 11
 */
public boolean isBlank()

1

Kırpma yöntemi sizin için harika çalışmalıdır.

http://download.oracle.com/docs/cd/E17476_01/javase/1.4.2/docs/api/java/lang/String.html#trim ()

Dizenin başında ve sonunda boşluk bırakılmış bir kopyasını döndürür. Bu String nesnesi boş bir karakter dizisini temsil ediyorsa veya bu String nesnesi tarafından temsil edilen karakter dizisinin ilk ve son karakterlerinin her ikisi de "\ u0020" den (boşluk karakteri) büyük kodlara sahipse, bu String nesnesine bir başvuru döndürülür.

Aksi takdirde, dizede "\ u0020" değerinden büyük bir koda sahip bir karakter yoksa, boş bir dizeyi temsil eden yeni bir String nesnesi oluşturulur ve döndürülür.

Aksi takdirde, dizedeki kodu "\ u0020" den büyük olan ilk karakterin dizini k olsun ve dizedeki kodu "\ u0020" den büyük olan son karakterin dizini m olsun. Bu dizenin k dizinindeki karakterle başlayan ve m dizinindeki karakterle biten alt dizesini temsil eden yeni bir String nesnesi oluşturulur - yani this.substring (k, m + 1) sonucudur.

Bu yöntem, bir dizenin başından ve sonundan boşlukları kırpmak için kullanılabilir; aslında, tüm ASCII kontrol karakterlerini de kırpar.

Döndürür: Bu dizenin başındaki ve sonundaki beyaz boşluk kaldırılmış bir kopyası veya bu dizenin başında veya sonunda beyaz boşluk yoksa, öndeki veya sondaki beyaz boşluk.

Kırpabilir ve sonra boş bir dizeyle karşılaştırabilir veya muhtemelen 0 için uzunluğu kontrol edebilirsiniz.


Cevapta bağlantı öldü - 404 | Üzgünüz, sayfa mevcut değil veya artık mevcut değil .
Pang

0

Alternatif:

boolean isWhiteSpaces( String s ) {
    return s != null && s.matches("\\s+");
 }

1
\\ s * boşluklu veya boşluksuz tüm dizelerle eşleşir. Belki \\ s + demek istediniz?
Rob Raisch

0

trim () ve belirtilen diğer düzenli ifadeler tüm beyaz boşluk türleri için çalışmaz

ör: Unicode Karakter 'LINE SEPARATOR' http://www.fileformat.info/info/unicode/char/2028/index.htm

Java işlevleri Character.isWhitespace () tüm durumları kapsar.

Bu nedenle, daha önce bahsedilen çözüm StringUtils.isWhitespace (String) / veya StringUtils.isBlank (String) kullanılmalıdır.



0

Openjdk 13, Windows 10'da sadece bir performans karşılaştırması. Bu metinlerin her biri için:

"abcd"
"    "
" \r\n\t"
" ab "
" \n\n\r\t   \n\r\t\t\t   \r\n\r\n\r\t \t\t\t\r\n\n"
"lorem ipsum dolor sit amet  consectetur adipisici elit"
"1234657891234567891324569871234567891326987132654798"

aşağıdaki testlerden birini gerçekleştirdi:

// trim + empty
input.trim().isEmpty()

// simple match
input.matches("\\S")

// match with precompiled pattern
final Pattern PATTERN = Pattern.compile("\\S");
PATTERN.matcher(input).matches()

// java 11's isBlank
input.isBlank()

her 10.000.000 kere.

Sonuçlar:

METHOD    min   max   note
trim:      18   313   much slower if text not trimmed
match:   1799  2010   
pattern:  571   662   
isBlank:   60   338   faster the earlier hits the first non-whitespace character

Oldukça şaşırtıcı bir şekilde, döşeme + boş en hızlı olanıdır. Kesilmiş metni oluşturması gerekse bile. Beyaz boşluklu olmayan tek bir karakter arayan döngüden daha hızlıdır ...

DÜZENLEME: Metin ne kadar uzunsa, sayılar o kadar farklı olur. Uzun metnin kırpılması, basit döngüden daha uzun sürer. Ancak regex'ler hala en yavaş çözümdür.


0

Kişisel olarak ben !str.isBlank(), başkalarının daha önce önerdiği gibi (veya str -> !str.isBlank()bir Dayanak olarak), str.trim()yukarıda bahsedilen yaklaşımın daha modern ve verimli bir versiyonunu tercih ediyor olsam da , boşları "boşluk" olarak str.strip()kabul ederek :

if (str != null && str.strip().length() > 0) {...}

Örneğin Predicate olarak, akışlarla kullanım için, örneğin bir birim testinde:

@Test
public void anyNonEmptyStrippedTest() {
    String[] strings = null;
    Predicate<String> isNonEmptyStripped = str -> str != null && str.strip().length() > 0;
    assertTrue(Optional.ofNullable(strings).map(arr -> Stream.of(arr).noneMatch(isNonEmptyStripped)).orElse(true));
    strings = new String[] { null, "", " ", "\\n", "\\t", "\\r" };
    assertTrue(Optional.ofNullable(strings).map(arr -> Stream.of(arr).anyMatch(isNonEmptyStripped)).orElse(true));
    strings = new String[] { null, "", " ", "\\n", "\\t", "\\r", "test" };
}
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.