Java String - Проверьте, содержит ли строка только цифры, а не буквы

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

<code>String text = "abc"; 
String number; 

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

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

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

Solution:

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

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

<code>String text = "abc"; 
String number; 

if (Pattern.matches("[a-zA-Z]+", text) == false && text.length() > 2) {
    number = text; 
}
</code>
 SARose29 янв. 2017 г., 16:34
@ RedHatccPattern.matches("[a-zA-Z]+", text) == false можно упростить до!Pattern.matches("[a-zA-Z]+", text)
 Yash13 дек. 2018 г., 14:55
Использование API потоковой передачи Javaboolean isNumeric = someString.chars().allMatch(x -> Character.isDigit(x)); формаMax Malysh После
 Doug Swain14 мая 2012 г., 00:09
Может ли строка иметь десятичное значение или только целочисленные значения?
 Guillaume Polet14 мая 2012 г., 00:07
contains не принимает регулярные выражения в качестве входных данных. Используйте либоmatches("\\d{2,}") или попробуйте сPattern а такжеMatcher
 Code Enthusiastic08 авг. 2013 г., 18:31
Почему вы проверяете text.length ()> 2? В чем причина

Ответы на вопрос(18)

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

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();
    }
}

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

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();
    }

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

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

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

 Y-B Cause27 нояб. 2017 г., 00:27
Мне не нуженtext.length() > 2 часть, поэтому я просто заменил^[0-9]*$ по^[0-9]+$ чтобы быть уверенным, что у меня есть хотя бы один номер.
 Abdull31 янв. 2018 г., 19:04
Я не думаюNumberUtil.isCreatable(String str) правильно использовать для того, что просит оригинальный вопрос. Например,NumberUtil.isCreatable( "09" ) возвращаетfalse, даже не смотря на"09" содержит только цифры.

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

Strings в Java (и наоборот). Вы можете пропустить часть регулярных выражений, чтобы избавить себя от осложнений.

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

 Doug Swain12 нояб. 2013 г., 03:02
@ OfirLuzon Я согласен, что исключения не являются отличным способом обработки ожидаемых случаев, которые могут возникнуть. Однако я думаю, что трудно сказать, будет ли снижение производительности без дополнительного контекста.
 Ofir Luzon11 нояб. 2013 г., 11:42
Использование исключения в качестве причины для проверки вашего ввода может быть плохой идеей, исключения создают большие накладные расходы.

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

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

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

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

Решение Вопроса

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).

 ctomek26 окт. 2015 г., 11:29
Нет необходимости звонить&& (text.length() > 2). Все можно проверить по шаблону регулярных выражений:if (text.matches("[0-9]{3,}")
 ICR13 сент. 2013 г., 23:37
Вы, вероятно, хотите добавить якоря (например,^[0-9]+$) иначеabc123def будет считаться числом.
 Chthonic Project12 дек. 2013 г., 18:59
Я не думаю, что это необходимо.matches() возвращает истину, если и только если это полное совпадение от начала до конца.
 CmdrShepardsPie04 дек. 2014 г., 20:59
"^ -? \ d + \.? \ d * !$40$!quot; будет сравнивать всю строку и совпадать только в том случае, если это допустимое число (включая минус и десятичные дроби). Например, он будет соответствовать 1, 10, 1.0, -1, -1.0 и т. Д. Он также будет соответствовать «1». но это часто можно проанализировать в любом случае.

если строка имеет только номер или нет:

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

Оба вышеуказанных условия вернутсяtrue if String содержит не числа. Наfalse, строка содержит только цифры.

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

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

 Leo28 авг. 2018 г., 23:44
Это должно быть намного быстрее, чем регулярное выражение; вот реализация:public static boolean isNumeric(String str) { if (str == null) { return false; } else { int sz = str.length(); for(int i = 0; i < sz; ++i) { if (!Character.isDigit(str.charAt(i))) { return false; } } return true; } }

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

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

Или вы можете использовать такие версии, как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
}
 CrandellWS24 сент. 2018 г., 17:16
.matches ( "^ \\ d + !$106$!quot;)
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;
    }
}

типичный сценарий.

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

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

Вы также можете использовать пользователяInteger.parseInt(String str) метод. Если ваша входная строка содержит только число, то она легко будет разбирать целое число, иначе она выдастNumberFormatException. Рассмотрим следующий фрагмент:

public static boolean isOnlyNumbers(String str){
        try{
            Integer.parseInt(str);
        }catch(NumberFormatException exception){
            return false;
        }
        return true;
    }

Вот тестовые случаи:

System.out.println(isOnlyNumbers("dssd")); // flase
System.out.println(isOnlyNumbers("123")); // true
System.out.println(isOnlyNumbers("123.4")); // false

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

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

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

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

Эти способы могут привести к разным результатам для строк, отличных от 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 без использования потока
 Aldo Canepa21 февр. 2018 г., 10:59
Если вы посмотрите на код toCharArray, он выделяет массив символов и копирует символы (я думаю, это может быть дорого). А что если вы просто итерируете строку, используя index и charAt, это будет быстрее? Было бы интересно также, если бы вы могли добавить решение от Энди в свои тесты: boolean isNum = text.chars (). AllMatch (c -> c> = 48 && c <= 57)

c> = 48 && c <= 57)

Вот мой код, надеюсь, он тебе поможет!

 
    boolean isDigit = false;

    if (text.matches("[0-9]+") && text.length() > 2) {
        isDigit = true;
    }else {
        isDigit = false;
    }

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

                }
                else if (Character.isLetter())
                {

                }

ctype_digit (), чтобы проверить, содержит ли строка только цифры.

это в своем коде:

if (ctype_digit(text) && text.length() > 2) {
    number = text; 
}

Ваш ответ на вопрос