Java String – Смотрите, содержит ли строка только числа, а не буквы

У меня есть строка, которую я загружаю по всему моему приложению, и она изменяется от чисел к буквам и тому подобное. У меня есть простая инструкция if чтобы увидеть, содержит ли она буквы или цифры, но что-то работает неправильно. Вот fragment.

 String text = "abc"; String number; if (text.contains("[a-zA-Z]+") == false && text.length() > 2) { number = text; } 

Хотя text переменная содержит буквы, условие возвращает значение true . И && должны анализировать, поскольку оба условия должны быть true , чтобы обрабатывать number = text;

==============================

Решение:

Я смог решить это, используя следующий код, предоставленный комментарием по этому вопросу. Все остальные сообщения также действительны!

То, что я использовал, работало с первого комментария. Хотя все приведенные примеры кода также являются действительными!

 String text = "abc"; String number; if (Pattern.matches("[a-zA-Z]+", text) == false && text.length() > 2) { number = text; } 

Если вы будете обрабатывать номер как текст, измените:

 if (text.contains("[a-zA-Z]+") == false && text.length() > 2){ 

чтобы:

 if (text.matches("[0-9]+") && text.length() > 2) { 

Вместо проверки того, что строка не содержит буквенных символов, убедитесь, что она содержит только цифры.

Если вы действительно хотите использовать числовое значение, используйте Integer.parseInt() или Double.parseDouble() как другие объяснили ниже.


В качестве побочного примечания обычно считается false практикой сравнивать логические значения с true или false . Просто используйте if (condition) или if (!condition) .

Вы также можете использовать NumberUtil.isCreatable (String str) из Apache Commons

Вот как я это сделаю:

 if(text.matches("^[0-9]*$") && text.length() > 2){ //... } 

$ Будет избегать частичного совпадения, например; 1B .

Производительность parseInt и такие намного хуже, чем другие решения, поскольку по крайней мере требуют обработки исключений.

Я запустил jmh-тесты и обнаружил, что итерация по String с использованием charAt и сравнение символов с граничными символами – это самый быстрый способ проверить, содержит ли строка только цифры.

Тест JMH

Тесты сравнивают производительность Character.isDigit vs. Pattern.matcher().matches Long.parseLong vs Long.parseLong и проверяет значения char.

Эти способы могут приводить к другому результату для строк без ascii и строк, содержащих знаки +/-.

Тесты проходят в режиме пропускной способности ( лучше – лучше ) с 5 итерациями прогрева и 5 тестовыми итерациями.

Результаты

Обратите внимание, что parseLong почти в 100 раз медленнее, чем isDigit для первой тестовой нагрузки.

 ## Test load with 25% valid strings (75% strings contain non-digit symbols) Benchmark Mode Cnt Score Error Units testIsDigit thrpt 5 9.275 ± 2.348 ops/s testPattern thrpt 5 2.135 ± 0.697 ops/s testParseLong thrpt 5 0.166 ± 0.021 ops/s ## Test load with 50% valid strings (50% strings contain non-digit symbols) Benchmark Mode Cnt Score Error Units testCharBetween thrpt 5 16.773 ± 0.401 ops/s testCharAtIsDigit thrpt 5 8.917 ± 0.767 ops/s testCharArrayIsDigit thrpt 5 6.553 ± 0.425 ops/s testPattern thrpt 5 1.287 ± 0.057 ops/s testIntStreamCodes thrpt 5 0.966 ± 0.051 ops/s testParseLong thrpt 5 0.174 ± 0.013 ops/s testParseInt thrpt 5 0.078 ± 0.001 ops/s 

Тестирование

 @State(Scope.Benchmark) public class StringIsNumberBenchmark { private static final long CYCLES = 1_000_000L; private static final String[] STRINGS = {"12345678901","98765432177","58745896328","35741596328", "123456789a1", "1a345678901", "1234567890 "}; private static final Pattern PATTERN = Pattern.compile("\\d+"); @Benchmark public void testPattern() { for (int i = 0; i < CYCLES; i++) { for (String s : STRINGS) { boolean b = false; b = PATTERN.matcher(s).matches(); } } } @Benchmark public void testParseLong() { for (int i = 0; i < CYCLES; i++) { for (String s : STRINGS) { boolean b = false; try { Long.parseLong(s); b = true; } catch (NumberFormatException e) { // no-op } } } } @Benchmark public void testCharArrayIsDigit() { for (int i = 0; i < CYCLES; i++) { for (String s : STRINGS) { boolean b = false; for (char c : s.toCharArray()) { b = Character.isDigit(c); if (!b) { break; } } } } } @Benchmark public void testCharAtIsDigit() { for (int i = 0; i < CYCLES; i++) { for (String s : STRINGS) { boolean b = false; for (int j = 0; j < s.length(); j++) { b = Character.isDigit(s.charAt(j)); if (!b) { break; } } } } } @Benchmark public void testIntStreamCodes() { for (int i = 0; i < CYCLES; i++) { for (String s : STRINGS) { boolean b = false; b = s.chars().allMatch(c -> c > 47 && c < 58); } } } @Benchmark public void testCharBetween() { for (int i = 0; i < CYCLES; i++) { for (String s : STRINGS) { boolean b = false; for (int j = 0; j < s.length(); j++) { char charr = s.charAt(j); b = '0' <= charr && charr <= '9'; if (!b) { break; } } } } } } 

Обновлено 23 февраля 2018 года

  • Добавьте еще два случая: один использует charAt вместо создания дополнительного массива, а другой - с помощью IntStream из кодов символов
  • Добавьте немедленный разрыв, если не указана цифра для зацикленных тестовых примеров
  • Вернуть false для пустой строки для зацикленных тестовых примеров

Обновлено 23 февраля 2018 года

  • Добавьте еще один тестовый пример (самый быстрый!), Который сравнивает значение char без использования streamа

Существует множество возможностей для получения чисел из String s на Java (и наоборот). Вы можете пропустить часть регулярного выражения, чтобы избавить себя от этого.

Например, вы можете попробовать и посмотреть, что Double.parseDouble(String s) вернется для вас. Он должен NumberFormatException если оно не находит подходящее значение в строке. Я бы предложил эту технику, потому что вы могли бы фактически использовать значение, представленное String как числовой тип.

boolean isNum = text.chars (). allMatch (c -> c> = 48 && c <= 57)

Вы можете использовать Regex.Match

 if(text.matches("\\d*")&& text.length() > 2){ System.out.println("number"); } 

Или вы можете использовать onversions, такие как Integer.parseInt(String) или лучше Long.parseLong(String) для больших чисел, например, например:

 private boolean onlyContainsNumbers(String text) { try { Long.parseLong(text); return true; } catch (NumberFormatException ex) { return false; } } 

И затем проверьте:

 if (onlyContainsNumbers(text) && text.length() > 2) { // do Stuff } 

Apache Commons Lang предоставляет org.apache.commons.lang.StringUtils.isNumeric(CharSequence cs) , который принимает в качестве аргумента String и проверяет, состоит ли она из чисто числовых символов (включая номера из нелатинских скриптов). Этот метод возвращает false если есть такие символы, как пробел, минус, плюс и десятичные разделители, такие как запятая и точка.

Другие методы этого classа позволяют проводить дополнительные числовые проверки.

Чтобы просто проверить строку, содержащую только ALPHABETS, используйте следующий код:

 if (text.matches("[a-zA-Z]+"){ // your operations } 

Чтобы просто проверить строку, содержащую только NUMBER, используйте следующий код:

 if (text.matches("[0-9]+"){ // your operations } 

Надеюсь, это поможет кому-то!

Этот код уже написан. Если вы не возражаете (крайне) незначительный удар производительности, что, вероятно, не хуже, чем выполнение регулярного выражения, используйте Integer.parseInt () или Double.parseDouble () . Это сразу скажет вам, если строка – это только числа (или число, если это необходимо). Если вам нужно обрабатывать более длинные строки чисел, как BigInteger, так и BigDecimal спортивные конструкторы, которые принимают строки. Любой из них будет вызывать исключение NumberFormatException, если вы попытаетесь передать ему не число (целое или десятичное, в зависимости от того, которое вы выберете, конечно). В качестве альтернативы, в зависимости от ваших требований, просто перебирайте символы в строке и проверяйте Character.isDigit () и / или Character.isLetter () .

 import java.util.*; class Class1 { public static void main(String[] argh) { boolean ans = CheckNumbers("123"); if (ans == true) { System.out.println("String contains numbers only"); } else { System.out.println("String contains other values as well"); } } public static boolean CheckNumbers(String input) { for (int ctr = 0; ctr < input.length(); ctr++) { if ("1234567890".contains(Character.valueOf(input.charAt(ctr)).toString())) { continue; } else { return false; } } return true; } } 

Ниже регулярных выражений можно использовать, чтобы проверить, имеет ли строка только номер или нет:

if (str.matches(".*[^0-9].*")) or if (str.matches(".*\\D.*"))

Оба условия выше вернут true если String содержит не номера. На false строка имеет только числа.

 Character first_letter_or_number = query.charAt(0); //------------------------------------------------------------------------------ if (Character.isDigit()) { } else if (Character.isLetter()) { } 

Рабочий пример тестирования

 import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; public class PaserNo { public static void main(String args[]) { String text = "gg"; if (!StringUtils.isBlank(text)) { if (stringContainsNumber(text)) { int no=Integer.parseInt(text.trim()); System.out.println("inside"+no); } else { System.out.println("Outside"); } } System.out.println("Done"); } public static boolean stringContainsNumber(String s) { Pattern p = Pattern.compile("[0-9]"); Matcher m = p.matcher(s); return m.find(); } } 

Тем не менее ваш код может быть разбит на «1a» и т. Д., Поэтому вам нужно проверить исключение

 if (!StringUtils.isBlank(studentNbr)) { try{ if (isStringContainsNumber(studentNbr)){ _account.setStudentNbr(Integer.parseInt(studentNbr.trim())); } }catch(Exception e){ e.printStackTrace(); logger.info("Exception during parse studentNbr"+e.getMessage()); } } 

Метод проверки нет – это строка или нет.

 private boolean isStringContainsNumber(String s) { Pattern p = Pattern.compile("[0-9]"); Matcher m = p.matcher(s); return m.find(); } 

Плохая практика заключается в том, чтобы задействовать любое исключение броска / обработки в такой типичный сценарий.

Поэтому parseInt () не является хорошим, но регулярное выражение является изящным решением для этого, но позаботьтесь о следующем:
-дробей
неотрицательные числа
-дискальный разделитель может различаться в зависимости (например, ‘,’ или ‘.’)
иногда разрешается иметь так называемый разделитель тысяч, например, пробел или запятую, например, 12 324 1000.55

Чтобы обрабатывать все необходимые случаи в вашем приложении, вы должны быть осторожны, но это регулярное выражение охватывает типичные сценарии (положительные / отрицательные и дробные, разделенные точкой): ^ [- +]? \ D *.? \ D + $
Для тестирования я рекомендую regexr.com .

Interesting Posts
Давайте будем гением компьютера.