985

文字列を解析する前に、文字列が数値であるかどうかをどのように確認しますか?

4

40 に答える 40

981

これは一般に、単純なユーザー定義関数 (つまり、ロール独自の「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.
}

ただし、上記の RegEx メカニズムには注意してください。アラビア語以外の数字 (つまり、0 ~ 9 以外の数字) を使用している場合は失敗します。これは、RegEx の "\d" 部分が [0-9] のみに一致し、実質的に国際的に数値を認識していないためです。(これを指摘してくれた OregonGhost に感謝します!)

または、Java の組み込み java.text.NumberFormat オブジェクトを使用して、文字列を解析した後、パーサーの位置が文字列の末尾にあるかどうかを確認することもできます。そうであれば、文字列全体が数値であると想定できます。

public static boolean isNumeric(String str) {
  ParsePosition pos = new ParsePosition(0);
  NumberFormat.getInstance().parse(str, pos);
  return str.length() == pos.getIndex();
}
于 2009-07-09T09:55:15.493 に答える
758

Apache Commons Lang 3.5 以降の場合:NumberUtils.isCreatableまたはStringUtils.isNumeric.

Apache Commons Lang 3.4 以下の場合:NumberUtils.isNumberまたはStringUtils.isNumeric.

StringUtils.isNumericSpace空の文字列を返しtrue、文字列内の内部スペースを無視する which を使用することもできます。もう1つの方法はNumberUtils.isParsable、Javaに従って数値が解析可能であることを基本的にチェックするものを使用することです。(リンクされた javadoc には、各メソッドの詳細な例が含まれています。)

于 2012-09-24T17:01:45.170 に答える
168

Java 8 ラムダ式。

String someString = "123123";
boolean isNumeric = someString.chars().allMatch( Character::isDigit );
于 2015-12-13T17:01:52.800 に答える
167

Android を使用している場合は、次を使用する必要があります。

android.text.TextUtils.isDigitsOnly(CharSequence str)

ドキュメントはここにあります

シンプルにしてください。ほとんどの人は「再プログラム」できます (同じこと)。

于 2013-11-22T21:34:48.480 に答える
133

@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 が指摘したように、上記のコードは正の整数のみを検証し、私のユース ケースの大部分をカバーします。以下は、システムで使用されているデフォルトのロケールに従って、10 進数を正しく検証する更新されたコードです。小数点区切り記号は文字列内で 1 回だけ発生するという前提があります。

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;
}
于 2011-08-17T11:30:23.340 に答える
44

Google の Guava ライブラリは、これを行うための優れたヘルパー メソッドを提供します: Ints.tryParse. 同様に使用しますが、文字列が有効な整数に解析されない場合、例外をスローするのではなく、Integer.parseInt戻ります。nullint ではなく 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 からの回答と似ていますが、わずかに異なる を使用しています。それらの実装の背後にある例外処理のオーバーヘッドはありません。

于 2012-01-29T20:13:07.767 に答える
30

例外を使用して値を検証しないでください。 apache NumberUtils のように代わりに Util ライブラリを使用します。

NumberUtils.isNumber(myStringValue);

編集

文字列が 0 で始まる場合、NumberUtils は値を 16 進数として解釈することに注意してください。

NumberUtils.isNumber("07") //true
NumberUtils.isNumber("08") //false
于 2015-08-31T14:14:04.687 に答える
20
public static boolean isNumeric(String str)
{
    return str.matches("-?\\d+(.\\d+)?");
}

CraigTPの正規表現(上に表示)は、いくつかの誤検知を生成します。たとえば、「23y4」は「。」であるため、数値としてカウントされます。小数点以外の任意の文字に一致します。

また、先頭に「+」が付いている番号はすべて拒否されます

これらの2つの小さな問題を回避する代替手段は次のとおりです。

public static boolean isNumeric(String str)
{
    return str.matches("[+-]?\\d*(\\.\\d+)?");
}
于 2011-09-17T16:56:36.657 に答える
15

使用できますNumberFormat#parse

try
{
     NumberFormat.getInstance().parse(value);
}
catch(ParseException e)
{
    // Not a number.
}
于 2009-07-09T09:53:58.447 に答える
8

これが問題に対する私の答えでした。

任意のタイプのパーサーで任意の文字列を解析するために使用できる便利なすべてのメソッドをキャッチ: isParsable(Object parser, String str). パーサーはClassまたはobjectです。これにより、作成したカスタム パーサーを使用することもでき、次のようなあらゆるシナリオで機能するはずです。

isParsable(Integer.class, "11");
isParsable(Double.class, "11.11");
Object dateFormater = new java.text.SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
isParsable(dateFormater, "2001.07.04 AD at 12:08:56 PDT");

これがメソッドの説明を含む私のコードです。

import java.lang.reflect.*;

/**
 * METHOD: isParsable<p><p>
 * 
 * This method will look through the methods of the specified <code>from</code> parameter
 * looking for a public method name starting with "parse" which has only one String
 * parameter.<p>
 * 
 * The <code>parser</code> parameter can be a class or an instantiated object, eg:
 * <code>Integer.class</code> or <code>new Integer(1)</code>. If you use a
 * <code>Class</code> type then only static methods are considered.<p>
 * 
 * When looping through potential methods, it first looks at the <code>Class</code> associated
 * with the <code>parser</code> parameter, then looks through the methods of the parent's class
 * followed by subsequent ancestors, using the first method that matches the criteria specified
 * above.<p>
 * 
 * This method will hide any normal parse exceptions, but throws any exceptions due to
 * programmatic errors, eg: NullPointerExceptions, etc. If you specify a <code>parser</code>
 * parameter which has no matching parse methods, a NoSuchMethodException will be thrown
 * embedded within a RuntimeException.<p><p>
 * 
 * Example:<br>
 * <code>isParsable(Boolean.class, "true");<br>
 * isParsable(Integer.class, "11");<br>
 * isParsable(Double.class, "11.11");<br>
 * Object dateFormater = new java.text.SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");<br>
 * isParsable(dateFormater, "2001.07.04 AD at 12:08:56 PDT");<br></code>
 * <p>
 * 
 * @param parser    The Class type or instantiated Object to find a parse method in.
 * @param str   The String you want to parse
 * 
 * @return true if a parse method was found and completed without exception
 * @throws java.lang.NoSuchMethodException If no such method is accessible 
 */
public static boolean isParsable(Object parser, String str) {
    Class theClass = (parser instanceof Class? (Class)parser: parser.getClass());
    boolean staticOnly = (parser == theClass), foundAtLeastOne = false;
    Method[] methods = theClass.getMethods();

    // Loop over methods
    for (int index = 0; index < methods.length; index++) {
        Method method = methods[index];

        // If method starts with parse, is public and has one String parameter.
        // If the parser parameter was a Class, then also ensure the method is static. 
        if(method.getName().startsWith("parse") &&
            (!staticOnly || Modifier.isStatic(method.getModifiers())) &&
            Modifier.isPublic(method.getModifiers()) &&
            method.getGenericParameterTypes().length == 1 &&
            method.getGenericParameterTypes()[0] == String.class)
        {
            try {
                foundAtLeastOne = true;
                method.invoke(parser, str);
                return true; // Successfully parsed without exception
            } catch (Exception exception) {
                // If invoke problem, try a different method
                /*if(!(exception instanceof IllegalArgumentException) &&
                   !(exception instanceof IllegalAccessException) &&
                   !(exception instanceof InvocationTargetException))
                        continue; // Look for other parse methods*/

                // Parse method refuses to parse, look for another different method
                continue; // Look for other parse methods
            }
        }
    }

    // No more accessible parse method could be found.
    if(foundAtLeastOne) return false;
    else throw new RuntimeException(new NoSuchMethodException());
}


/**
 * METHOD: willParse<p><p>
 * 
 * A convienence method which calls the isParseable method, but does not throw any exceptions
 * which could be thrown through programatic errors.<p>
 * 
 * Use of {@link #isParseable(Object, String) isParseable} is recommended for use so programatic
 * errors can be caught in development, unless the value of the <code>parser</code> parameter is
 * unpredictable, or normal programtic exceptions should be ignored.<p>
 * 
 * See {@link #isParseable(Object, String) isParseable} for full description of method
 * usability.<p>
 * 
 * @param parser    The Class type or instantiated Object to find a parse method in.
 * @param str   The String you want to parse
 * 
 * @return true if a parse method was found and completed without exception
 * @see #isParseable(Object, String) for full description of method usability 
 */
public static boolean willParse(Object parser, String str) {
    try {
        return isParsable(parser, str);
    } catch(Throwable exception) {
        return false;
    }
}
于 2011-11-28T11:26:06.497 に答える
7

ASCII 数字のみを含む正の 10 進整数のみを照合するには、次を使用します。

public static boolean isNumeric(String maybeNumeric) {
    return maybeNumeric != null && maybeNumeric.matches("[0-9]+");
}
于 2014-08-14T13:02:23.540 に答える
7

try-catch を回避し、負の数と科学表記法を処理する優れたアプローチ。

Pattern PATTERN = Pattern.compile( "^(-?0|-?[1-9]\\d*)(\\.\\d+)?(E\\d+)?$" );

public static boolean isNumeric( String value ) 
{
    return value != null && PATTERN.matcher( value ).matches();
}
于 2014-03-17T11:56:53.630 に答える
7

正規表現マッチング

これは、より多くの検証を使用してアップグレードされた「CraigTP」正規表現マッチングの別の例です。

public static boolean isNumeric(String str)
{
    return str.matches("^(?:(?:\\-{1})?\\d+(?:\\.{1}\\d+)?)$");
}
  1. マイナス記号は 1 つだけ-許可され、先頭になければなりません。
  2. マイナス記号の後には数字が必要です。
  3. 小数点記号は 1 つだけ.使用できます。
  4. 小数点の後には数字が必要です。

正規表現テスト

1                  --                   **VALID**
1.                 --                   INVALID
1..                --                   INVALID
1.1                --                   **VALID**
1.1.1              --                   INVALID

-1                 --                   **VALID**
--1                --                   INVALID
-1.                --                   INVALID
-1.1               --                   **VALID**
-1.1.1             --                   INVALID
于 2015-06-15T06:10:35.207 に答える
5

// 以下のコードを確認してください

public static boolean isDigitsOnly(CharSequence str) {
    final int len = str.length();
    for (int i = 0; i < len; i++) {
        if (!Character.isDigit(str.charAt(i))) {
            return false;
        }
    }
    return true;
}
于 2016-09-16T12:57:17.957 に答える
5

これは、文字列が数値かどうかをチェックするための私のクラスです。また、数値文字列も修正されます。

特徴:

  1. 不要なゼロを削除 ["12.0000000" -> "12"]
  2. 不要なゼロを削除 ["12.0580000" -> "12.058"]
  3. 数字以外の文字を削除 ["12.00sdfsdf00" -> "12"]
  4. 負の文字列値 ["-12,020000" -> "-12.02"] を処理します
  5. 複数のドットを削除 ["-12.0.20.000" -> "-12.02"]
  6. 追加のライブラリはなく、標準の Java のみ

どうぞ...

public class NumUtils {
    /**
     * Transforms a string to an integer. If no numerical chars returns a String "0".
     *
     * @param str
     * @return retStr
     */
    static String makeToInteger(String str) {
        String s = str;
        double d;
        d = Double.parseDouble(makeToDouble(s));
        int i = (int) (d + 0.5D);
        String retStr = String.valueOf(i);
        System.out.printf(retStr + "   ");
        return retStr;
    }

    /**
     * Transforms a string to an double. If no numerical chars returns a String "0".
     *
     * @param str
     * @return retStr
     */
    static String makeToDouble(String str) {

        Boolean dotWasFound = false;
        String orgStr = str;
        String retStr;
        int firstDotPos = 0;
        Boolean negative = false;

        //check if str is null
        if(str.length()==0){
            str="0";
        }

        //check if first sign is "-"
        if (str.charAt(0) == '-') {
            negative = true;
        }

        //check if str containg any number or else set the string to '0'
        if (!str.matches(".*\\d+.*")) {
            str = "0";
        }

        //Replace ',' with '.'  (for some european users who use the ',' as decimal separator)
        str = str.replaceAll(",", ".");
        str = str.replaceAll("[^\\d.]", "");

        //Removes the any second dots
        for (int i_char = 0; i_char < str.length(); i_char++) {
            if (str.charAt(i_char) == '.') {
                dotWasFound = true;
                firstDotPos = i_char;
                break;
            }
        }
        if (dotWasFound) {
            String befDot = str.substring(0, firstDotPos + 1);
            String aftDot = str.substring(firstDotPos + 1, str.length());
            aftDot = aftDot.replaceAll("\\.", "");
            str = befDot + aftDot;
        }

        //Removes zeros from the begining
        double uglyMethod = Double.parseDouble(str);
        str = String.valueOf(uglyMethod);

        //Removes the .0
        str = str.replaceAll("([0-9])\\.0+([^0-9]|$)", "$1$2");

        retStr = str;

        if (negative) {
            retStr = "-"+retStr;
        }

        return retStr;

    }

    static boolean isNumeric(String str) {
        try {
            double d = Double.parseDouble(str);
        } catch (NumberFormatException nfe) {
            return false;
        }
        return true;
    }

}
于 2014-10-07T11:08:05.920 に答える
4

java.util.Scanner オブジェクトを使用できます。

public static boolean isNumeric(String inputData) {
      Scanner sc = new Scanner(inputData);
      return sc.hasNextInt();
    }
于 2015-08-19T07:52:20.000 に答える
3
// only int
public static boolean isNumber(int num) 
{
    return (num >= 48 && c <= 57); // 0 - 9
}

// is type of number including . - e E 
public static boolean isNumber(String s) 
{
    boolean isNumber = true;
    for(int i = 0; i < s.length() && isNumber; i++) 
    {
        char c = s.charAt(i);
        isNumber = isNumber & (
            (c >= '0' && c <= '9') || (c == '.') || (c == 'e') || (c == 'E') || (c == '')
        );
    }
    return isInteger;
}

// is type of number 
public static boolean isInteger(String s) 
{
    boolean isInteger = true;
    for(int i = 0; i < s.length() && isInteger; i++) 
    {
        char c = s.charAt(i);
        isInteger = isInteger & ((c >= '0' && c <= '9'));
    }
    return isInteger;
}

public static boolean isNumeric(String s) 
{
    try
    {
        Double.parseDouble(s);
        return true;
    }
    catch (Exception e) 
    {
        return false;
    }
}
于 2012-12-19T15:42:46.657 に答える
3

これは、このチェックの簡単な例です。

public static boolean isNumericString(String input) {
    boolean result = false;

    if(input != null && input.length() > 0) {
        char[] charArray = input.toCharArray();

        for(char c : charArray) {
            if(c >= '0' && c <= '9') {
                // it is a digit
                result = true;
            } else {
                result = false;
                break;
            }
        }
    }

    return result;
}
于 2014-09-15T10:48:50.203 に答える
2

そのため、.NETのTry*アプローチが気に入っています。Javaのような従来のParseメソッドに加えて、TryParseメソッドもあります。私はJava構文(パラメータ外?)が苦手なので、以下をある種の擬似コードとして扱ってください。しかし、それは概念を明確にするはずです。

boolean parseInteger(String s, out int number)
{
    try {
        number = Integer.parseInt(myString);
        return true;
    } catch(NumberFormatException e) {
        return false;
    }
}

使用法:

int num;
if (parseInteger("23", out num)) {
    // Do something with num.
}
于 2009-07-09T10:12:20.890 に答える
2

それを解析して(つまり でInteger#parseInt)、単純に例外をキャッチします。=)

明確にするために: parseInt 関数は、どのような場合でも(明らかに)数値を解析できるかどうかをチェックし、とにかく解析したい場合は、実際に解析を行うことでパフォーマンスに影響を与えることはありません。

それを解析したくない場合 (または非常にめったに解析したくない場合) は、もちろん別の方法で解析することをお勧めします。

于 2009-07-09T09:53:12.550 に答える
2

CraigTP のソリューションを変更して、科学表記法とドットとコンマの両方を小数点として受け入れるようにしました

^-?\d+([,\.]\d+)?([eE]-?\d+)?$

var re = new RegExp("^-?\d+([,\.]\d+)?([eE]-?\d+)?$");
re.test("-6546"); // true
re.test("-6546355e-4456"); // true
re.test("-6546.355e-4456"); // true, though debatable
re.test("-6546.35.5e-4456"); // false
re.test("-6546.35.5e-4456.6"); // false
于 2013-12-05T14:40:17.060 に答える
2

Java 8 ストリーム、ラムダ式、関数型インターフェース

すべてのケースが処理されます (文字列 null、文字列が空など)

String someString = null; // something="", something="123abc", something="123123"

boolean isNumeric = Stream.of(someString)
            .filter(s -> s != null && !s.isEmpty())
            .filter(Pattern.compile("\\D").asPredicate().negate())
            .mapToLong(Long::valueOf)
            .boxed()
            .findAny()
            .isPresent();
于 2016-05-11T05:10:15.583 に答える
1

文字列が数値かどうかを確実に判断する唯一の方法は、それを解析することだと思います。だから私はそれを解析するだけで、それが数値の場合、無料でintで数値を取得できます!

于 2009-07-09T09:54:05.217 に答える
1

BigDecimal文字列に小数が含まれている可能性がある場合は、次のように使用できます。

try {
    new java.math.BigInteger(testString);
} catch(NumberFormatException e) {
    throw new RuntimeException("Not a valid number");
}
于 2012-04-06T20:19:05.517 に答える
1

うまくいくかもしれない2つの方法を次に示します。(例外を使用しない場合)。注 : Java はデフォルトで値渡しであり、文字列の値は文字列のオブジェクト データのアドレスです。だから、あなたがやっているとき

stringNumber = stringNumber.replaceAll(" ", "");

入力値が変更され、スペースが含まれなくなりました。必要に応じて、その行を削除できます。

private boolean isValidStringNumber(String stringNumber)
{
    if(stringNumber.isEmpty())
    {
        return false;
    }

    stringNumber = stringNumber.replaceAll(" ", "");

    char [] charNumber = stringNumber.toCharArray();
    for(int i =0 ; i<charNumber.length ;i++)
    {
        if(!Character.isDigit(charNumber[i]))
        {
            return false;
        }
    }
    return true;
}

フロートを許可する場合の別の方法を次に示します。この方法では、フォーム内の数値が 1,123,123,123,123,123.123 を渡すことができると言われています。

private boolean isValidStringTrueNumber(String stringNumber)
{
    if(stringNumber.isEmpty())
    {
        return false;
    }

    stringNumber = stringNumber.replaceAll(" ", "");
    int countOfDecimalPoint = 0;
    boolean decimalPointPassed = false;
    boolean commaFound = false;
    int countOfDigitsBeforeDecimalPoint = 0;
    int countOfDigitsAfterDecimalPoint =0 ;
    int commaCounter=0;
    int countOfDigitsBeforeFirstComma = 0;

    char [] charNumber = stringNumber.toCharArray();
    for(int i =0 ; i<charNumber.length ;i++)
    {
        if((commaCounter>3)||(commaCounter<0))
        {
            return false;
        }
        if(!Character.isDigit(charNumber[i]))//Char is not a digit.
        {
            if(charNumber[i]==',')
            {
                if(decimalPointPassed)
                {
                    return false;
                }
                commaFound = true;
                //check that next three chars are only digits.
                commaCounter +=3;
            }
            else if(charNumber[i]=='.')
            {
                decimalPointPassed = true;
                countOfDecimalPoint++;
            }
            else
            {
                return false;
            }
        }
        else //Char is a digit.
        {
            if ((commaCounter>=0)&&(commaFound))
            {
                if(!decimalPointPassed)
                {
                    commaCounter--;
                }
            }

            if(!commaFound)
            {
                countOfDigitsBeforeFirstComma++;
            }

            if(!decimalPointPassed)
            {
                countOfDigitsBeforeDecimalPoint++;
            }
            else
            {
                countOfDigitsAfterDecimalPoint++;
            }
        }
    }
    if((commaFound)&&(countOfDigitsBeforeFirstComma>3))
    {
        return false;
    }
    if(countOfDecimalPoint>1)
    {
        return false;
    }

    if((decimalPointPassed)&&((countOfDigitsBeforeDecimalPoint==0)||(countOfDigitsAfterDecimalPoint==0)))
    {
        return false;
    }
    return true;
}
于 2013-04-19T18:34:26.390 に答える
0
String text="hello 123";
if(Pattern.matches([0-9]+))==true
System.out.println("String"+text);
于 2015-08-10T11:58:57.223 に答える
-2
import java.util.Scanner;

public class TestDemo {
    public static void main(String[] args) {
        boolean flag = true;
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the String:");
        String str = sc.nextLine();

        for (int i = 0; i < str.length(); i++) {
            if(str.charAt(i) > 48 && str.charAt(i) < 58) {
                flag = false;
                break;
            }
        }

        if(flag == true) {
            System.out.println("String is a valid String.");
        } else {
            System.out.println("String contains number.");
        }
    }
}
于 2013-12-21T16:16:18.453 に答える