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

в:

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){
    //...
}

на $ позволит избежать частичного совпадения e.g;1B.


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

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

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

тесты сравнения производительности Character.isDigit vs Pattern.matcher().matches vs Long.parseLong vs проверка значений 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 (и наоборот). Возможно, вы захотите пропустить часть regex, чтобы избавить себя от этого усложнения.

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


boolean isNum = текст.пеструшки.)(allMatch (c -> c >= 48 && c


вы можете использовать регулярное выражение.Матч

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), который принимает в качестве аргумента a String и проверяет, состоит ли он из чисто числовых символов (включая числа из нелатинских скриптов). Этот метод возвращает false Если есть символы, такие как пробел, минус, плюс и десятичные разделители, такие как запятая и точка.

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


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

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

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

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

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


этот код уже написан. Если вы не против (очень) малой производительности-это, вероятно, не хуже, чем regex матча-используйте целое число.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;
    }
}

ниже regexs можно использовать, чтобы проверить, имеет ли строка только номер или нет:

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

оба условия выше вернутся true если строка содержит не цифры. On 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.355

To обрабатывать все необходимые случаи в вашем приложении вы должны быть осторожны, но это регулярное выражение охватывает типичные сценарии (положительные/отрицательные и дробные, разделенные точкой): ^[-+]?\д.*?\д$+
для тестирования я рекомендую 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;
}