[java] Java String-문자열에 문자가 아닌 숫자 만 포함되어 있는지 확인

응용 프로그램 전체에로드 할 문자열이 있으며 숫자에서 문자 등으로 변경됩니다. if문자 또는 숫자가 포함되어 있는지 확인 하는 간단한 설명이 있지만 제대로 작동하지 않습니다. 다음은 스 니펫입니다.

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()다른 것을 사용하십시오 .


부수적으로 일반적으로 부울 값을 true또는 과 비교하는 것은 나쁜 습관으로 간주됩니다 false. if (condition)또는을 사용하십시오 if (!condition).


답변

Apache Commons에서 NumberUtil.isCreatable (String str) 을 사용할 수도 있습니다.


답변

이것이 내가하는 방법입니다.

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

$부분 일치 예를 방지 할 수 있습니다; 1B.


답변

parseInt최소한 예외 처리가 필요하기 때문에 성능 측면 에서는 다른 솔루션보다 훨씬 나쁩니다.

jmh 테스트를 실행했으며 문자열을 사용하여 문자열을 반복하고 charAt문자를 경계 문자와 비교하는 것이 문자열에 숫자 만 포함되어 있는지 테스트하는 가장 빠른 방법 이라는 것을 알았습니다 .

JMH 테스트

테스트는 char 값 과 vs. char 값의 성능을 Character.isDigit비교 합니다.Pattern.matcher().matchesLong.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;
                    }
                }
            }
        }
    }
}

2018 년 2 월 23 일에 업데이트 됨

  • 추가 charAt배열을 만드는 대신 사용 IntStream하고 문자 코드를 사용 하는 경우를 두 개 더 추가하십시오.
  • 반복 테스트 사례에 대해 숫자가 아닌 숫자가 발견되면 즉시 중단 추가
  • 반복 테스트 사례의 빈 문자열에 대해서는 false를 반환

2018 년 2 월 23 일에 업데이트 됨

  • 스트림을 사용하지 않고 문자 값을 비교하는 테스트 케이스를 하나 더 추가하십시오 (가장 빠름).

답변

ALPHABETS 만 포함 된 문자열을 간단히 확인하려면 다음 코드를 사용하십시오.

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

NUMBER 만 포함하는 문자열을 간단히 확인하려면 다음 코드를 사용하십시오.

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

이것이 누군가에게 도움이되기를 바랍니다!


답변

부울 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
}