Як я можу перевірити, що Java String - це не всі пробіли?


132

Я хочу перевірити, що Java String або масив символів не просто складається з пробілів, використовуючи Java?

Це дуже схоже питання, окрім Javascript:
Як я можу перевірити, чи рядок містить символи та пробіли, а не просто пробіли?

EDIT : Я видалив трохи про буквено-цифрові символи, тому це має більше сенсу.


3
Пам’ятайте, що існує багато різних визначень пробілів: Spreadsheets.google.com/pub?key=pd8dAQyHbdewRsnE5x5GzKQ Які ви хочете? Або тоді ви кажете "має буквено-цифровий характер", що зовсім інша річ. Поясніть будь ласка.
Кевін Бурліон

Вибачення за плутанину ... не всі пробіли є ключовим - в основному, якщо в ньому є всі символи пробілу, я хочу його виключити, оскільки він не має змісту.
Анкур

1
З JDK / 11 ви можете використовуватиString.isBlank API для того ж.
Наман

Відповіді:


224

Найкоротше рішення, про яке я можу придумати:

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

Це перевіряє лише (не) пробіл. Якщо ви хочете перевірити для конкретних класів символів, вам потрібно скористатись могутніми match()з регулярним виразом, наприклад:

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

... який перевіряє наявність хоча б одного буквено-цифрового символу (ASCII).


9
FWIW: Я б очікував, що перше рішення буде значно швидшим.
Стівен С

2
@Stephen C: Абсолютно! Але як зазначав @Uri, мені доводиться вирішувати дві різні проблеми завдяки неоднозначності питання :) Також я рідко використовую matches(): для продуктивності я зазвичай зберігаю Patternв final static. Окупається, якщо один і той же код працює часто.
Карл Смотрич

3
@Andreas_D: Хе, я отримав свої замовлення! ОП заявив, що хоче перевірити рядок або масив char, він ніколи нічого не сказав про нулі! :) * перевіряє тонкий шрифт у договорі * " nullне рядок!"
Карл Смотрич

1
Крім того, "\\ w" відповідає лише обмеженому набору символів, які не є пробілами, а не всім пробілам, оскільки вони відносяться до "символів слова", визначених як AZ, az, 0-9 та підкреслення.
Роб Райш

2
Я використав your_string.trim (). IsEmpty () і зробив роботу для мене
Нері

59

Я використовував би бібліотеку Apache Commons Lang. У ньому є клас під назвою StringUtils, який корисний для всіляких операцій String. Щоб перевірити, чи струна не є всіма пробілами, ви можете скористатися наступним:

StringUtils.isBlank(<your string>)

Ось посилання: StringUtils.isBlank


8
Я вважаю за краще це рішення порівняно з використанням обраної відповіді. Це також перевірить на рядок == null
Річард

Зараз це неправильно. StringUtils.isEmptyтепер поверне помилкове значення, якщо ви перейдете в "".
Джеймс Спенс

53

Трохи коротший від того, що згадував Карл Смотрич:

!string.trim().isEmpty();

10
Ви, молоді юнаки та ваші новомодні хитрощі після Java-1.6! Серйозно, щонайменше один проект моєї компанії все ще працює на Java 1.4 (зітхає).
Карл Смотрич

Коротше? Так. Особисто мені подобається більш багатослівний стиль кодування
Мішель


9

Якщо ви використовуєте Java 11 , новий isBlankметод рядка стане у нагоді:

!s.isBlank();

Якщо ви використовуєте Java 8, 9 або 10 , ви можете створити простий потік, щоб перевірити, що рядок не є лише пробілом:

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

Окрім того, що вони не потребують сторонніх бібліотек, таких як Apache Commons Lang, ці рішення мають перевагу в обробці будь-якими символами пробілу, а не просто ' 'просторами, як trimрішення, що базується на багатьох інших відповідях. Ви можете звернутися до Javadocs для вичерпного списку всіх підтримуваних типів пробілів. Зауважте, що порожні рядки також охоплені в обох випадках.


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

Зверніть увагу на використання зворотної косої риски-S, що означає "не-пробіл"

Я би ставлю, що це найпростіше (і, можливо, найшвидший?) Рішення.


2
Спробуйте: String year="1995"; year.matches("\\S"); will return falseОтже, це невірне рішення. : |
Нхат Дінь

6
Ні, ти маєш рацію, хоча я в невдачі пояснюю, чому. Згідно з документами Java, String.matches перевіряє, чи відповідає даний рядок регексу. Невеликий експеримент показує, що це не зовсім точно, оскільки, здається, ця функція відповідає ТІЛЬКИ, якщо наданий регекс відповідає цілому рядку! Отже, зміна регулярного виразу ("\\ S") на "^. * \\ S. * $" Буде працювати так, як очікувалося, хоча ця поведінка не задокументована правильно і, схоже, суттєво відрізняється від будь-якої іншої реалізації збігу рядків використовуючи регулярні вирази.
Роб Райш

4

Ця відповідь більше акцентує увагу на стороні " тобто має принаймні один буквено-цифровий символ ". Крім того, він не додає занадто багато іншого (більш раннього) рішення, за винятком того, що він не зашкодить вам NPE у випадку, якщо String є null.

Ми хочемо, falseякщо (1) s є nullабо (2) s порожнім або (3) s містить тільки побілки.

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

4

Якщо ви перевіряєте лише пробіл і не турбуєтесь про null, ви можете використовувати org.apache.commons.lang.StringUtils.isWhitespace (String str),

StringUtils.isWhitespace(String str);

(Перевіряє, чи містить рядок лише пробіл.)

Якщо ви також хочете перевірити наявність нуля (включаючи пробіли), тоді

StringUtils.isBlank(String str);

isBlank (String) рекомендується, оскільки він також обробляє нульову перевірку!
Sachidananda Naik

2

З Java-11 + ви можете скористатися String.isBlankAPI, щоб перевірити, чи не вказана рядок складається з пробілів -

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

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

Явадок для того ж:

/**
 * 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

Метод обрізки повинен відмінно працювати для вас.

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

Повертає копію рядка з пропущеним пробілом та пробілом. Якщо цей об'єкт String являє собою порожню послідовність символів, або перший і останній символи послідовності символів, представлені цим об'єктом String, мають коди, що перевищують \ \ u0020 '(пробільний символ), повертається посилання на цей об'єкт String.

В іншому випадку, якщо в рядку немає символу з кодом, більшим за '\ u0020', створюється і повертається новий об'єкт String, що представляє порожню рядок.

В іншому випадку нехай k - індекс першого символу в рядку, код якого більше, ніж '\ u0020', і нехай m - індекс останнього символу в рядку, код якого більше, ніж '\ u0020'. Створюється новий об'єкт String, що представляє підрядку цього рядка, що починається з символу в індексі k і закінчується символом в індексі m - тобто результатом цього.substring (k, m + 1).

Цей метод може бути використаний для обрізки пробілів від початку та до кінця рядка; насправді він також обробляє всі символи управління ASCII.

Повертає: копія цього рядка з вилученим проміжним проміжним білим пробілом, або ця рядок, якщо в ній немає провідної або кінцевої пробілів.

Ви можете обрізати, а потім порівняти з порожнім рядком або, можливо, перевірити довжину на 0.


Посилання у відповідь мертве - 404 | На жаль, сторінка не існує або більше недоступна .
Панг

0

Альтернатива:

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

1
\\ s * буде відповідати всім рядкам з пробілами або без них. Можливо, ви маєте на увазі \\ s +?
Роб Райш

0

trim () та інші згадані регулярні вирази не працюють для всіх типів пробілів

тобто: Символ Unicode 'LINE SEPARATOR' http://www.fileformat.info/info/unicode/char/2028/index.htm

Функції Java Character.isWhitespace () охоплює всі ситуації.

Ось чому слід використовувати вже згадане рішення StringUtils.isWhitespace (String) / або StringUtils.isBlank (String) .


0
StringUtils.isEmptyOrWhitespaceOnly(<your string>)

перевіримо: - чи недійсне - чи це лише пробіл - чи порожній рядок ""

https://www.programcreek.com/java-api-examples/?class=com.mysql.jdbc.StringUtils&method=isEmptyOrWhitespaceOnly


1
Це з бібліотеки? Посилання на проект. Або вбудований у Java? Вкажіть пакет.
Василь Бурк

@BasilBourque Я думаю, що це com.mysql.jdbc.StringUtils.isEmptyOrWhitespaceOnly
ahmet_y

0

Просто порівняння продуктивності на openjdk 13, Windows 10. Для кожного з цих текстів:

"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"

виконали один із наступних тестів:

// 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()

кожні 10 000 000 разів.

Результати:

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

Досить дивно, що обробка + порожня - найшвидша. Навіть якщо для цього потрібно побудувати обрізаний текст. Ще швидше, ніж простий цикл, який шукає одного єдиного символу без пробілу ...

EDIT: Чим довший текст, тим більше цифр відрізняється. Обрізка довгого тексту займає більше часу, ніж просто простір. Однак регулярні вирази все ще є найповільнішим рішенням.


0

Хоча особисто я вважаю за краще !str.isBlank(), як інші, що вже пропонували (або str -> !str.isBlank()як предикат), використовував би більш сучасну та ефективну версію str.trim()підходу, згаданого вище str.strip()- розглядаючи нулі як "пробіли":

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

Наприклад, як предикат, для використання з потоками, наприклад, в одиничному тесті:

@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" };
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.