web-dev-qa-db-ja.com

Java String - ストリングが数字だけを含み、文字が含まれていないかどうかを調べる

アプリケーション全体にロードする文字列があり、それが数字から文字などに変わります。文字や数字が含まれているかどうかを確認するための単純なifステートメントを使用しましたが、正しく機能していません。これがスニペットです。

String text = "abc"; 
String number; 

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

text変数には文字が含まれていますが、条件はtrueとして返されます。 &&を処理するためには、とnumber = text;は両方の条件がtrueでなければならないと評価されるべきです。

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

解決策:

この質問へのコメントで提供されている次のコードを使用して、これを解決できました。他のすべての投稿も有効です。

私が使ったのは最初のコメントからきたものです。提供されているすべてのサンプルコードも有効であるようですが!

String text = "abc"; 
String number; 

if (Pattern.matches("[a-zA-Z]+", text) == false && text.length() > 2) {
    number = text; 
}
155
RedHatcc

数字をテキストとして処理する場合は、次のように変更します。

if (text.contains("[a-zA-Z]+") == false && text.length() > 2){

に:

if (text.matches("[0-9]+") && text.length() > 2) {

が含まれていないことを確認する代わりに、 only numericsが含まれていることを確認してください。

実際に数値を使用したい場合は、他で説明しているようにInteger.parseInt()またはDouble.parseDouble()を使用してください。


補足として、ブール値をtrueまたはfalseと比較することは、一般的には悪い習慣と考えられています。 if (condition)またはif (!condition)を使うだけです。

304
Adam Liss

Apache Commonsの NumberUtil.isCreatable(String str) を使用することもできます。

20
Dhrumil Shah

これが私のやり方です。

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

$は部分一致を回避します。 1B

11
tokhi

パフォーマンス面でのparseIntなどは、少なくとも例外処理が必要なため、他のソリューションよりもはるかに劣ります。

私はjmhテストを実行し、charAtを使用して文字列を反復処理し、文字列と数字を比較することが、文字列が数字のみを含むかどうかをテストする最も速い方法であることを発見しました。

JMHテスト

テストはCharacter.isDigitPattern.matcher().matches vs Long.parseLong対char値のチェックのパフォーマンスを比較します。

これらの方法では、非ASCII文字列と+/-記号を含む文字列では異なる結果が生じる可能性があります。

テストは、5回のウォームアップと5回のテストで、スループットモード( 大きいほど良い )で実行されます。

結果

最初のテストロードでは、parseLongisDigitよりもほぼ100倍遅くなります。

## 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日に更新

  • さらに2つのケースを追加します。1つは追加の配列を作成する代わりにcharAtを使用する方法、もう1つはcharコードのIntStreamを使用する方法です。
  • ループされたテストケースで数字以外が見つかった場合はすぐにブレークを追加する
  • ループテストケースの空の文字列に対してはfalseを返します

2018年2月23日に更新

  • Streamを使用せずにchar値を比較するもう1つのテストケース(最速!)を追加します。
6
Anton R

Apache Commons Lang org.Apache.commons.lang.StringUtils.isNumeric(CharSequence cs) を提供します。これは引数としてStringを取り、それが純粋な数字(ラテン文字以外のスクリプトの数字も含む)で構成されているかどうかをチェックします。スペース、マイナス、プラス、カンマやドットなどの小数点記号などの文字がある場合、このメソッドはfalseを返します。

そのクラスの他のメソッドはさらなる数値チェックを可能にします。

2
Abdull

ブールisNum = text.chars()。allMatch(c - > c> = 48 && c <= 57)

2
Andy

JavaではStringsから数値を取得するための多くの機能があります(その逆も同様です)。あなたは自分自身にその複雑さを避けるために正規表現の部分を飛ばしたくなるかもしれません。

たとえば、 Double.parseDouble(String s) が何を返すかを試してみることができます。文字列内に適切な値が見つからない場合はNumberFormatExceptionをスローします。 Stringで表される値を数値型として実際に利用できるので、この手法をお勧めします。

1
pseudoramble

Regex.Matchを使うことができます

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

あるいは、Integer.parseInt(String)のようなonversionsを使うことも、より大きな数のために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
}
1
Lag

以下の正規表現は、文字列に数字しかないかどうかを確認するために使用できます。

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

Stringが非数を含む場合、上記の両方の条件はtrueを返します。 falseでは、stringは数字だけを持ちます。

1

アルファベットのみを含む文字列を単純にチェックするには、次のコードを使用します。

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

NUMBERのみが含まれていることを確認するには、次のコードを使用します。

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

これが誰かに役立つことを願っています!

1
Aman Gupta

このコードはすでに書かれています。 (極端に)マイナーなパフォーマンスへの影響を気にしないのであれば - これはおそらく正規表現のマッチよりも悪いことではない - Integer.parseInt() または Double.parseDouble() 。 Stringが数字だけの場合(または が適切な場合は numberの場合)、すぐにわかります。もっと長い文字列を処理する必要がある場合は、 BigIntegerBigDecimal の両方のStringを受け入れるスポーツコンストラクタです。非数値(もちろん、選択した数値に基づいて整数または10進数)を渡さないと、 NumberFormatException がスローされます。あるいは、要件に応じて、文字列内の文字を反復して Character.isDigit() または Character.isLetter() 、あるいはその両方をチェックするだけです。

0
Ryan Stewart

そのような典型的なシナリオに例外のスロー/処理を含めることは悪い習慣です。

したがって、parseInt()はNiceではありませんが、正規表現はこれに対する洗練された解決策ですが、次の点に注意してください。
- 分数
- 負の数
- 小数点の区切り記号は国によって異なる場合があります(例: '、'、 '。')
- スペースやカンマのように、いわゆる1000の区切り記号を使用することが許可されることがあります。 12,324,1000.355

アプリケーションで必要なすべてのケースを処理するには注意が必要ですが、この正規表現は典型的なシナリオ(正/負および小数、ドット区切り)をカバーしています。
テストには、 regexr.com をお勧めします。

0
Adam Bodrogi
Character first_letter_or_number = query.charAt(0);
                //------------------------------------------------------------------------------
                if (Character.isDigit())
                {

                }
                else if (Character.isLetter())
                {

                }
0
JamisonMan111

作業テスト例

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

Noをチェックする方法は文字列か否か

private boolean isStringContainsNumber(String s) {
        Pattern p = Pattern.compile("[0-9]");
        Matcher m = p.matcher(s);
        return m.find();
    }
0
vaquar khan

これが私のコードです。これが役に立つことを願っています!

 public boolean isDigitOnly(String text){

    boolean isDigit = false;

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

    return 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;
    }
}
0
Usman Javaid