Java String-смотрите, если строка содержит только цифры, а не буквы
у меня есть строка, которую я загружаю по всему моему приложению, и она меняется от цифр до букв и т. д. У меня есть простой if утверждение, чтобы увидеть, если он содержит буквы или цифры, но что-то не совсем корректно работает. Вот фрагмент.
String text = "abc";
String number;
if (text.contains("[a-zA-Z]+") == false && text.length() > 2) {
number = text;
}
хотя text переменная содержит буквы, состояние как true. То и && должны eval как оба условия должны быть true для того чтобы обрабатывать number = text;
==============================
устранение:
я смог решить эту проблему, используя следующий код, предоставленный комментарием по этому вопросу. Все остальные сообщения также действительны!
то, что я использовал, что сработало, пришло из первого комментария. Хотя все приведенные примеры кодов, по-видимому, также действительны!
String text = "abc";
String number;
if (Pattern.matches("[a-zA-Z]+", text) == false && text.length() > 2) {
number = text;
}
16 ответов:
если вы будете обрабатывать число как текст, то измените:
if (text.contains("[a-zA-Z]+") == false && text.length() > 2){to:
if (text.matches("[0-9]+") && text.length() > 2) {вместо того, чтобы проверить, что строка не содержать буквенные символы, убедитесь, что он содержит только числа.
если вы действительно хотите использовать числовое значение, используйте
Integer.parseInt()илиDouble.parseDouble()как уже объяснили ниже.
в качестве примечания, как правило, считается плохой практикой для сравнения логические значения в
trueилиfalse. Просто используйтеif (condition)илиif (!condition).
вы также можете использовать NumberUtil.isCreatable (String str) от Apache Commons
вот как я бы это сделал:
if(text.matches("^[0-9]*$") && text.length() > 2){ //... }The
$позволит избежать частичного совпадения, например;1B.
производительность-мудрый
parseIntи такие гораздо хуже, чем другие решения, потому что по крайней мере требуют обработки исключений.Я запустил тесты jmh и обнаружил, что итерация по строке с помощью
charAtи сравнение символов с граничными символами-это самый быстрый способ проверить, содержит ли строка только цифры.тестирование JMH
тесты сравнения производительности
Character.isDigitvsPattern.matcher().matchesvsLong.parseLongvs проверка значений 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
есть много объектов, чтобы получить номера от
Strings в Java (и наоборот). Вы можете пропустить часть регулярных выражений, чтобы избавить себя от этого осложнения.например, вы можете попробовать и посмотреть, что
Double.parseDouble(String s)возвращает для вас. Он должен броситьNumberFormatExceptionесли он не находит соответствующее значение в строке. Я бы предложил этот метод, потому что вы могли бы использовать значение, представленноеStringКак числовой тип.
вы можете использовать регулярное выражение.Матч
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), который принимает в качестве аргумента aStringи проверяет, состоит ли он из чисто числовых символов (включая числа из нелатинских скриптов). Этот метод возвращаетfalseЕсли есть символы, такие как пробел, минус, плюс и десятичные разделители, такие как запятая и точка.другие методы этого класса позволяют проводить дальнейшие числовые проверки.
чтобы просто проверить строку, которая содержит только алфавиты, используйте следующий код:
if (text.matches("[a-zA-Z]+"){ // your operations }чтобы просто проверить строку, которая содержит только число, используйте следующий код:
if (text.matches("[0-9]+"){ // your operations }надеюсь, это поможет кому-то!
этот код уже написан. Если вы не возражаете против (чрезвычайно) незначительного хита производительности-что, вероятно, не хуже, чем выполнение регулярного выражения-используйте целое число.parseInt() или двойной.parseDouble(). Это сразу скажет вам, если строка-это только числа (или это число, по мере необходимости). Если вам нужно обрабатывать более длинные строки чисел, оба BigInteger и BigDecimal спорт конструкторы, которые принимают строки. Любой из них они будут бросать NumberFormatException Если вы попытаетесь передать ему не число (целое или десятичное, на основе того, который вы выбираете, конечно). Поочередно, в зависимости от ваших требований, просто повторите символы в строке и проверьте символ.isDigit() и/или
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если строка содержит не цифры. На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. 355To обрабатывать все необходимые случаи в вашем приложении вы должны быть осторожны, но это регулярное выражение охватывает типичные сценарии (положительные/отрицательные и дробные, разделенные точкой): ^[-+]?\д.*?\д$+
для тестирования я рекомендую regexr.com.
вот мой код, надеюсь это поможет вам !
public boolean isDigitOnly(String text){ boolean isDigit = false; if (text.matches("[0-9]+") && text.length() > 2) { isDigit = true; }else { isDigit = false; } return isDigit; }
Comments