[java] Java에서 문자열이 숫자인지 확인하는 방법

문자열을 구문 분석하기 전에 숫자인지 어떻게 확인합니까?



답변

아파치 코 몬즈 랭 3.5 이상 : NumberUtils.isCreatableStringUtils.isNumeric.

아파치 코 몬즈 랭 3.4 이하 : NumberUtils.isNumberStringUtils.isNumeric.

빈 문자열에 대한 StringUtils.isNumericSpace반환 값 true을 사용 하고 문자열의 내부 공간을 무시할 수도 있습니다 . 또 다른 방법은 NumberUtils.isParsable기본적으로 Java에 따라 파싱 가능한 수를 확인하는 사용 하는 것입니다. 링크 된 javadoc에는 각 메소드에 대한 자세한 예제가 포함되어 있습니다.


답변

이것은 일반적으로 간단한 사용자 정의 함수 (예 : Roll-your-own “isNumeric”함수)로 수행됩니다.

다음과 같은 것 :

public static boolean isNumeric(String str) { 
  try {  
    Double.parseDouble(str);  
    return true;
  } catch(NumberFormatException e){  
    return false;  
  }  
}

그러나이 함수를 많이 호출하고 숫자가 아니기 때문에 많은 검사가 실패 할 것으로 예상하면이 메커니즘의 성능은 좋지 않습니다. 각 실패마다 예외가 발생하기 때문입니다. 상당히 비싼 작업입니다.

다른 방법은 정규식을 사용하여 숫자의 유효성을 검사하는 것입니다.

public static boolean isNumeric(String str) {
  return str.matches("-?\\d+(\\.\\d+)?");  //match a number with optional '-' and decimal.
}

그러나 아랍어 이외의 숫자 (예 : 0에서 9 이외의 숫자)를 사용하면 위의 RegEx 메커니즘에주의해야합니다. 이는 RegEx의 “\ d”부분이 [0-9]에만 일치하고 효과적으로 국제적으로 숫자를 인식하지 못하기 때문입니다. (OregonGhost에게 이것을 지적 해 주셔서 감사합니다!)

또는 다른 대안은 Java의 내장 java.text.NumberFormat 객체를 사용하여 문자열을 구문 분석 한 후 구문 분석기 위치가 문자열의 끝에 있는지 확인하는 것입니다. 그렇다면 전체 문자열이 숫자라고 가정 할 수 있습니다.

public static boolean isNumeric(String str) {
  NumberFormat formatter = NumberFormat.getInstance();
  ParsePosition pos = new ParsePosition(0);
  formatter.parse(str, pos);
  return str.length() == pos.getIndex();
}


답변

당신이 안드로이드에 있다면, 당신은 사용해야합니다 :

android.text.TextUtils.isDigitsOnly(CharSequence str)

설명서는 여기에서 찾을 수 있습니다

간단하게 유지하십시오 . 대부분의 사람들은 “다시 프로그래밍”할 수 있습니다 (같은 것).


답변

Java 8 람다 식.

String someString = "123123";
boolean isNumeric = someString.chars().allMatch( Character::isDigit );


답변

@CraigTP가 그의 탁월한 답변에서 언급했듯이 예외를 사용하여 문자열이 숫자인지 여부를 테스트하는 것과 비슷한 성능 문제가 있습니다. 그래서 문자열을 나누고을 사용 java.lang.Character.isDigit()합니다.

public static boolean isNumeric(String str)
{
    for (char c : str.toCharArray())
    {
        if (!Character.isDigit(c)) return false;
    }
    return true;
}

에 따르면 Javadoc을 , Character.isDigit(char)의지가 제대로 라틴어가 아닌 숫자를 인식합니다. 성능 측면에서, N이 문자열의 문자 수인 간단한 N 수의 비교는 정규식 일치를 수행하는 것보다 계산적으로 효율적이라고 생각합니다.

업데이트 : 의견에서 Jean-François Corbett이 지적한 것처럼 위의 코드는 양의 정수 만 유효성을 검사하므로 대부분의 유스 케이스를 포괄합니다. 다음은 시스템에서 사용되는 기본 로케일에 따라 소수를 올바르게 유효성 검증하는 업데이트 된 코드이며 소수 구분 기호는 문자열에서 한 번만 발생한다는 가정입니다.

public static boolean isStringNumeric( String str )
{
    DecimalFormatSymbols currentLocaleSymbols = DecimalFormatSymbols.getInstance();
    char localeMinusSign = currentLocaleSymbols.getMinusSign();

    if ( !Character.isDigit( str.charAt( 0 ) ) && str.charAt( 0 ) != localeMinusSign ) return false;

    boolean isDecimalSeparatorFound = false;
    char localeDecimalSeparator = currentLocaleSymbols.getDecimalSeparator();

    for ( char c : str.substring( 1 ).toCharArray() )
    {
        if ( !Character.isDigit( c ) )
        {
            if ( c == localeDecimalSeparator && !isDecimalSeparatorFound )
            {
                isDecimalSeparatorFound = true;
                continue;
            }
            return false;
        }
    }
    return true;
}


답변

Google의 구아바 라이브러리는 다음과 같은 유용한 도우미 방법을 제공합니다 Ints.tryParse. 당신은 같이 사용할 수 Integer.parseInt있지만 반환 null이 아닌 문자열이 유효한 정수로 구문 분석하지 않는 경우 예외를 throw합니다. int가 아닌 Integer를 반환하므로 int로 다시 변환 / 오토 박스해야합니다.

예:

String s1 = "22";
String s2 = "22.2";
Integer oInt1 = Ints.tryParse(s1);
Integer oInt2 = Ints.tryParse(s2);

int i1 = -1;
if (oInt1 != null) {
    i1 = oInt1.intValue();
}
int i2 = -1;
if (oInt2 != null) {
    i2 = oInt2.intValue();
}

System.out.println(i1);  // prints 22
System.out.println(i2);  // prints -1

그러나 현재 릴리스 인 Guava r11에서는 여전히 @Beta로 표시되어 있습니다.

나는 그것을 벤치마킹하지 않았습니다. 소스 코드를 보면 많은 온 전성 검사로 인한 오버 헤드가 있지만 결국 Character.digit(string.charAt(idx))@Ibrahim의 대답과 비슷하지만 약간 다릅니다. 구현시 커버 아래에서 예외 처리 오버 헤드가 없습니다.


답변

값을 확인하기 위해 예외를 사용하지 마십시오.
아파치 NumberUtils 대신 Util 라이브러리를 사용하십시오 :

NumberUtils.isNumber(myStringValue);

편집 :

문자열이 0으로 시작하면 NumberUtils는 값을 16 진수로 해석합니다.

NumberUtils.isNumber("07") //true
NumberUtils.isNumber("08") //false