Как проверить, что строка Java не состоит только из пробелов?

132

Я хочу проверить, что Java String или символьный массив не состоит только из пробелов, используя Java?

Это очень похожий вопрос, за исключением Javascript:
Как я могу проверить, содержит ли строка символы и пробелы, а не только пробелы?

РЕДАКТИРОВАТЬ : я удалил бит об алфавитно-цифровых символах, поэтому он имеет больше смысла.

Анкур
источник
3
Имейте в виду, что существует множество различных определений пробелов: spreadsheets.google.com/pub?key=pd8dAQyHbdewRsnE5x5GzKQ Что вы хотите? Или тогда вы говорите «имеет буквенно-цифровой символ», что совсем другое дело. Просьба уточнить.
Кевин Бурриллион,
Приносим извинения за путаницу ... не все пробелы являются ключевыми - в основном, если в нем есть все символы пробелов, я хочу исключить его, потому что у него нет содержимого.
Ankur
1
С JDK / 11 вы можете использоватьString.isBlank API для того же.
Наман

Ответы:

224

Кратчайшее решение, которое я могу придумать:

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

Это проверяет только наличие (не) пробелов. Если вы хотите проверить определенные классы символов, вам нужно использовать могущество match()с регулярным выражением, например:

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

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

Карл Смотриц
источник
9
FWIW: Я ожидал, что первое решение будет значительно быстрее.
Stephen C
2
@Stephen C: Совершенно верно! Но, как заметил @Uri, мне приходится решать две разные проблемы из-за двусмысленности вопроса :) Кроме того, я редко использую matches(): для производительности я обычно храню Patternв файле final static. Окупается, если один и тот же код запускается часто.
Carl Smotricz
3
@Andreas_D: Хех, я получил приказ! ОП сказал, что хочет проверить массив строк или символов, он никогда ничего не говорил о нулях! :) * проверяет мелкий шрифт в контракте * " nullне строка!"
Carl Smotricz
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теперь вернет false, если вы передадите "".
Джеймс Спенс
53

Немного короче, чем то, что сказал Карл Смотриц:

!string.trim().isEmpty();
redslime
источник
10
Вы, молодые козлы, и ваш новомодный трюк после Java-1.6! Серьезно, по крайней мере один проект в моей компании все еще работает на Java 1.4 (вздох).
Carl Smotricz
Более короткие? Да. Лично мне нравится более подробный стиль кодирования
Мишель
9

Если вы используете Java 11 , вам isBlankпригодится новый строковый метод:

!s.isBlank();

Если вы используете Java 8, 9 или 10 , вы можете создать простой поток, чтобы проверить, не является ли строка только пробелом:

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

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

Pyves
источник
5
if(target.matches("\\S")) 
    // then string contains at least one non-whitespace character

Обратите внимание на использование символа обратной косой черты cap-S, что означает "непробельный символ".

Держу пари, что это простейшее (и, возможно, самое быстрое?) Решение.

Роб Райш
источник
2
Давай попробуем: String year="1995"; year.matches("\\S"); will return falseЗначит, это неправильное решение. : |
Нхат Динь
6
Нет, вы правы, хотя я не могу объяснить почему. Согласно документам Java, String.matches проверяет, соответствует ли данная строка регулярному выражению. Небольшое экспериментирование показывает, что это не совсем точно, поскольку эта функция соответствует ТОЛЬКО в том случае, если предоставленное регулярное выражение соответствует ВСЕЙ строке! Таким образом, изменение регулярного выражения выше ("\\ S") на "^. * \\ S. * $" Будет работать должным образом, хотя это поведение не задокументировано должным образом и, по-видимому, существенно отличается от любой другой реализации сопоставления строк. с использованием регулярных выражений.
Роб Райш
4

В этом ответе больше внимания уделяется примечанию « т.е. есть хотя бы один буквенно-цифровой символ ». Кроме того, это не добавляет слишком много к другому (более раннему) решению, за исключением того, что это не повредит вам с NPE в случае, если Stringnull .

Нам нужно, 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);

(Проверяет, содержит ли строка только пробелы.)

Если вы также хотите проверить значение null (включая пробелы), тогда

StringUtils.isBlank(String str);
Arun
источник
isBlank (String) рекомендуется, так как он также обрабатывает нулевую проверку!
Сачидананда Найк,
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

Javadoc для того же:

/**
 * 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()
Naman
источник
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, то есть результатом this.substring (k, m + 1).

Этот метод можно использовать для обрезки пробелов в начале и в конце строки; фактически, он также обрезает все управляющие символы ASCII.

Возвращает: копию этой строки с удаленными начальными и конечными пробелами или эту строку, если у нее нет начальных или конечных пробелов. Начальные или конечные пробелы.

Вы можете обрезать, а затем сравнить с пустой строкой или, возможно, проверить длину на 0.

Кори Огберн
источник
Ссылка в ответе мертва - 404 | К сожалению, страница не существует или больше не доступна .
Pang
0

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

boolean isWhiteSpaces( String s ) {
    return s != null && s.matches("\\s+");
 }
OscarRyz
источник
1
\\ s * будет соответствовать всем строкам с пробелами или без них. Возможно вы имеете в виду \\ s +?
Роб Райш
0

trim () и другие упомянутые регулярные выражения не работают для всех типов пробелов

т.е.: символ Юникода "СТРОКА РАЗДЕЛИТЕЛЬ" http://www.fileformat.info/info/unicode/char/2028/index.htm

Функции Java Character.isWhitespace () охватывают все ситуации.

Поэтому следует использовать уже упомянутое решение StringUtils.isWhitespace (String) / или StringUtils.isBlank (String) .

andreyro
источник
0
StringUtils.isEmptyOrWhitespaceOnly(<your string>)

проверит: - это ноль - это только пробел - это пустая строка ""

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

akakargul
источник
1
Это из библиотеки? Ссылка на проект. Или встроен в Java? Укажите упаковку.
Basil Bourque
@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

Удивительно, но трим + пустой - самый быстрый. Даже если ему нужно построить обрезанный текст. Еще быстрее, чем простой цикл for, ищущий один единственный символ без пробелов ...

РЕДАКТИРОВАТЬ: чем длиннее текст, тем больше различаются числа. Обрезка длинного текста занимает больше времени, чем простой цикл. Однако регулярные выражения по-прежнему являются самым медленным решением.

martlin
источник
0

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

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

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

@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" };
}
fozzybear
источник