Javaで文字列から数字を抽出する


207

Java Stringオブジェクトがあります。数字のみを抽出する必要があります。例を挙げましょう:

"123-456-789" が欲しいです "123456789"

数字のみを抽出するライブラリ関数はありますか?

答えてくれてありがとう。これらを試す前に、追加のライブラリをインストールする必要があるかどうかを知る必要がありますか?

回答:


545

正規表現を使用して、数字以外を削除できます。

str = str.replaceAll("\\D+","");

6
素敵な短いコード。線形検索の方が速いかもしれませんが、あなたの方が理にかなっていると思います。
kasten

18
私はあなたが好きなものなら何でも反対投票することができると思います(皮肉は意図していません)しかし、私の個人的な見解は次のとおりです。優れた開発者(そしてここにはたくさんの開発者がいます)が彼らのアドバイスの一部を無料で共有した場合、私はそれを尊重します。比率は、17xxダウンに対して14xxです)。しかし、それは私の個人的な哲学であり、あなたはあなた自身のものを持つことが自由です。
Sean Patrick Floyd、

78
これは、数値に小数点がある場合は機能しません。小数点も削除されます。str = str.replaceAll("[^\\.0123456789]","");
Aravindan R 2012

2
正規表現は非常にシンプルで見た目はきれいですが、パフォーマンスの問題が発生するため、1回限りのストリップ(フォーム送信など)がある場合にのみ使用してください。大量のデータを処理している場合、これは適切な方法ではありません。
Brill Pappin、

2
小数点などを除外する必要がある場合(?!\\.)
azerafati

49

これは、より詳細なソリューションです。エレガントではありませんが、おそらく高速です:

public static String stripNonDigits(
            final CharSequence input /* inspired by seh's comment */){
    final StringBuilder sb = new StringBuilder(
            input.length() /* also inspired by seh's comment */);
    for(int i = 0; i < input.length(); i++){
        final char c = input.charAt(i);
        if(c > 47 && c < 58){
            sb.append(c);
        }
    }
    return sb.toString();
}

テストコード:

public static void main(final String[] args){
    final String input = "0-123-abc-456-xyz-789";
    final String result = stripNonDigits(input);
    System.out.println(result);
}

出力:

0123456789

ところで、Character.isDigit(ch)は0〜9以外の多くの文字を受け入れるため、使用しませんでした。


4
StringBuilderコンストラクター(などinput.length())にサイズを指定して、再割り当てする必要がないことを確認する必要があります。Stringここを要求する必要はありません。CharSequence十分です。また、入力としてStringBuilderaを受け取り、出力アキュムレータとしてインスタンスを受け取る別の関数を記述することにより、非数字のコレクションからの割り当てを分離できます。CharSequenceAppendable
seh 2010年

1
@seh面白そうですが、コメントするのではなく、拡張機能を使用して独自の回答を作成してみませんか?
RedYeti

3
@RedYetiこの回答をそのままにし、コメントを追加することは、ショーンがその時点で賛成票を受け取るため、より名誉なことです。また、急いでいる場合は、コードを書き直すよりも他の人のコードを批評する方がはるかに迅速です。価値のある貢献をしたことでsehを罰しないでください。彼はそれらの有用な情報を追加する必要はありませんでした。
KomodoDave

2
私は誰も「罰せない」わけではありません-それは私が@sehに言っていたことの完全な誤解です。私の指摘は、彼のコメントは非常に価値のあるものを追加し、実際には非常に大きく変化したため、それ自体の答えを正当化するものだと感じました。ショーン・パトリック・フロイドは他の人を助けるだけの称賛に関心がなく、sehが彼自身の答えを提供することに完全に満足していると確信しています。彼の貢献にもっと目を向ける価値があると感じたので、私は単にsehを励ましただけでした。他の何かとして私のコメントを読むことがどのように可能であるかは私を完全に困惑させますが、それがどういうわけかそうしたなら、私はsehに謝罪します。
RedYeti 2013

1
私は、これらの議論がしばらく休眠した後に起きるのが好きです。おそらく、ここで最善の方法は、ショーンの回答を編集して、私の提案でそれを補強することです。そうすれば、回答がコミュニティウィキステータスに移行しない限り、ショーンはクレジットを受け取り続けます。
seh 2013

22
public String extractDigits(String src) {
    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < src.length(); i++) {
        char c = src.charAt(i);
        if (Character.isDigit(c)) {
            builder.append(c);
        }
    }
    return builder.toString();
}

私はCharacter.isDigit()を自分で使用することを考えましたが、0-9以外の一部の文字も受け入れます(ドキュメント:download.oracle.com/javase/6/docs/api/java/lang/…を参照)
Sean Patrickフロイド

21

Google Guavaの使用:

CharMatcher.inRange('0','9').retainFrom("123-456-789")

更新:

事前計算されたCharMatcherを使用すると、パフォーマンスをさらに向上させることができます

CharMatcher ASCII_DIGITS=CharMatcher.inRange('0','9').precomputed();  
ASCII_DIGITS.retainFrom("123-456-789");

3
現在、Charmatcher.DIGIT事前定義されています。
ダンカンマクレガー

15
input.replaceAll("[^0-9?!\\.]","")

これは小数点を無視します。

例:入力445.3kgが出力の場合はになります445.3


「4.5 zi」があります。2番目を維持するため、機能しません。また
MarianKlühspies16年

11

Google Guavaの使用:

CharMatcher.DIGIT.retainFrom("123-456-789");

CharMatcherはプラグイン可能で、使用するのが非常に興味深いです。たとえば、次のことができます。

String input = "My phone number is 123-456-789!";
String output = CharMatcher.is('-').or(CharMatcher.DIGIT).retainFrom(input);

出力== 123-456-789


非常に優れたソリューション(+1)ですが、他の問題と同じ問題があります。多くの文字は、ASCII数字だけでなく、Unicode数字としても使用できます。このコードは、これらの文字をすべて保持します:unicode.org/cldr/utility/list-unicodeset.jsp?a
Sean Patrick Floyd

@seanizer:その後、これはより良いCharMatcher.inRange( '1'、 '9')。retainFrom( "123-456-789")
Emil

@EmilはCharMatcher.inRange( '0'、 '9')に似ていますが、:はい
Sean Patrick Floyd

inRangeはCharMatcher.DIGITの背後にあるものです。pastie.org/1252471 これは、単に状況に応じたUTF番号の範囲を考慮に入れているだけですが、実際にはそうであるので、これらは単にASCIIエンコードされていないため、数字と見なします。
BjornS

同じ目的でCharMatcher.JAVA_DIGITを使用することもできます。これは、Character.isDigit
BjornS

6

正規表現を使用して要件に一致させます。

String num,num1,num2;
String str = "123-456-789";
String regex ="(\\d+)";
Matcher matcher = Pattern.compile( regex ).matcher( str);
while (matcher.find( ))
{
num = matcher.group();     
System.out.print(num);                 
}

5

私はコードSean Patrick Floydからインスピレーションを得て、得られる最大のパフォーマンスを得るために少し書き直しました。

public static String stripNonDigitsV2( CharSequence input ) {
    if (input == null)
        return null;
    if ( input.length() == 0 )
        return "";

    char[] result = new char[input.length()];
    int cursor = 0;
    CharBuffer buffer = CharBuffer.wrap( input );

    while ( buffer.hasRemaining() ) {
        char chr = buffer.get();
        if ( chr > 47 && chr < 58 )
            result[cursor++] = chr;
    }

    return new String( result, 0, cursor );
}

私は最小限の数で非常に長い文字列に対してパフォーマンステストを行い、結果は次のとおりです。

  • 元のコードは25,5%遅い
  • グアバのアプローチは2.5-3倍遅い
  • D +による正規表現は3〜3.5倍遅い
  • Dのみの正規表現は25+倍遅い

ところでそれはその文字列の長さに依存します。文字列が6つだけ含まれている場合、グアバは50%遅くなり、正規表現は1倍遅くなります


4
public class FindDigitFromString 
{

    public static void main(String[] args) 
    {
        String s="  Hi How Are You 11  ";        
        String s1=s.replaceAll("[^0-9]+", "");
        //*replacing all the value of string except digit by using "[^0-9]+" regex.*
       System.out.println(s1);          
   }
}

出力: 11



2

電話番号+9(987)124124のコードを確定しました。

Unicode文字は4バイトを占めます。

public static String stripNonDigitsV2( CharSequence input ) {
    if (input == null)
        return null;
    if ( input.length() == 0 )
        return "";

    char[] result = new char[input.length()];
    int cursor = 0;
    CharBuffer buffer = CharBuffer.wrap( input );
    int i=0;
    while ( i< buffer.length()  ) { //buffer.hasRemaining()
        char chr = buffer.get(i);
        if (chr=='u'){
            i=i+5;
            chr=buffer.get(i);
        }

        if ( chr > 39 && chr < 58 )
            result[cursor++] = chr;
        i=i+1;
    }

    return new String( result, 0, cursor );
}

2

コード:

public class saasa {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String t="123-456-789";
        t=t.replaceAll("-", "");
        System.out.println(t);
    }

0
import java.util.*;
public class FindDigits{

 public static void main(String []args){
    FindDigits h=new  FindDigits();
    h.checkStringIsNumerical();
 }

 void checkStringIsNumerical(){
    String h="hello 123 for the rest of the 98475wt355";
     for(int i=0;i<h.length();i++)  {
      if(h.charAt(i)!=' '){
       System.out.println("Is this '"+h.charAt(i)+"' is a digit?:"+Character.isDigit(h.charAt(i)));
       }
    }
 }

void checkStringIsNumerical2(){
    String h="hello 123 for 2the rest of the 98475wt355";
     for(int i=0;i<h.length();i++)  {
         char chr=h.charAt(i);
      if(chr!=' '){
       if(Character.isDigit(chr)){
          System.out.print(chr) ;
       }
       }
    }
 }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.