Ekstrak digit dari string di Jawa


207

Saya punya Stringobjek Java . Saya perlu mengekstraksi hanya digit dari itu. Saya akan memberi contoh:

"123-456-789" saya ingin "123456789"

Apakah ada fungsi perpustakaan yang mengekstrak hanya digit?

Terima kasih atas jawabannya. Sebelum saya mencoba ini, saya perlu tahu apakah saya harus menginstal perpustakaan tambahan?

Jawaban:


546

Anda dapat menggunakan regex dan menghapus non-digit.

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

6
kode pendek yang bagus. Pencarian linear mungkin lebih cepat tetapi saya pikir milik Anda lebih masuk akal.
kasten

18
Saya kira Anda dapat downvote apa pun yang Anda suka downvote (tidak ada sarkasme yang dimaksudkan) Tetapi pendapat pribadi saya adalah: ketika pengembang hebat (dan kami memiliki banyak di sini) membagikan beberapa saran mereka secara gratis, maka saya akan menghormatinya, dan saya hanya meng-downvote hal-hal yang benar-benar mengerikan (lihat profil saya, saat ini saya rasio 14xx naik terhadap 17 turun). Tapi itu filosofi pribadi saya dan Anda bebas untuk memiliki Anda sendiri.
Sean Patrick Floyd

78
Ini tidak akan berfungsi jika nomor Anda memiliki titik desimal, itu menghilangkan titik desimal juga. str = str.replaceAll("[^\\.0123456789]","");
Aravindan R

2
Meskipun regex sangat sederhana dan bersih untuk dilihat, ia menderita masalah kinerja dan hanya boleh digunakan di mana Anda memiliki strip satu kali (seperti formulir pengiriman). Jika Anda memproses banyak data, ini bukan cara yang tepat.
Brill Pappin

2
dan jika Anda perlu mengecualikan apa pun, seperti titik desimal,(?!\\.)
azerafati

49

Inilah solusi yang lebih bertele-tele. Kurang anggun, tapi mungkin lebih cepat:

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

Kode Tes:

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

Keluaran:

0123456789

BTW: Saya tidak menggunakan Character.isDigit (ch) karena menerima banyak karakter lain kecuali 0 - 9.


4
Anda harus memberikan ukuran kepada StringBuilderkonstruktor (seperti input.length()) untuk memastikan bahwa itu tidak perlu realokasi. Anda tidak perlu menuntut di Stringsini; CharSequencecukup. Anda juga dapat memisahkan alokasi dari StringBuilderkoleksi non-digit dengan menulis fungsi terpisah yang menerima CharSequenceinput as dan Appendableinstance sebagai akumulator output.
seh

1
@ Seh Kedengarannya menarik tetapi daripada berkomentar mengapa tidak membuat jawaban Anda sendiri dengan ekstensi?
RedYeti

3
@RedYeti Membiarkan jawaban ini tetap dan menambahkan komentar lebih terhormat karena Sean menerima upvotes saat itu. Ini juga jauh lebih cepat untuk mengkritik kode orang lain daripada menulis ulang jika Anda sedang terburu-buru. Jangan menghukum seh karena memberikan kontribusi yang berharga, ia tidak perlu menambahkan informasi berguna itu, dan respons Anda membuatnya lebih kecil kemungkinannya melakukannya di lain waktu.
KomodoDave

2
Saya tidak "menghukum" siapa pun - itu adalah kesalahpahaman sepenuhnya atas apa yang saya katakan kepada @seh. Maksud saya adalah bahwa komentarnya menambahkan begitu banyak yang bermanfaat dan pada kenyataannya banyak berubah sehingga saya merasa itu menjamin jawaban itu sendiri. Saya yakin Sean Patrick Floyd tidak peduli dengan pujian hanya membantu orang lain dan akan senang sekali dengan memberikan jawabannya sendiri. Saya hanya mendorong seh karena saya merasa kontribusinya layak visibilitas yang lebih besar. Bagaimana mungkin untuk membaca komentar saya sebagai hal lain benar-benar membingungkan saya, tetapi saya minta maaf kepada seh jika entah bagaimana melakukannya.
RedYeti

1
Saya suka bagaimana diskusi ini mengambil setelah berbaring tidak aktif untuk sementara waktu. Mungkin hal terbaik untuk dilakukan di sini adalah saya mengedit jawaban Sean, menambahkannya dengan saran saya. Dengan begitu, Sean akan terus menerima kredit kecuali jika jawabannya beralih ke status wiki komunitas.
seh

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

Saya berpikir untuk menggunakan Character.isDigit () sendiri, tetapi ia juga menerima beberapa karakter yang bukan 0-9 (lihat dokumen: download.oracle.com/javase/6/docs/api/java/lang/… )
Sean Patrick Floyd

21

Menggunakan Google Guava:

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

MEMPERBARUI:

Menggunakan Precomputed CharMatcher dapat lebih meningkatkan kinerja

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

3
Sekarang sudah Charmatcher.DIGITditentukan sebelumnya.
Duncan McGregor

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

Ini akan mengabaikan poin desimal.

misalnya: jika Anda memiliki input sebagai 445.3kgoutput 445.3.


Saya punya "4,5 zi." tidak bekerja karena itu menjaga yang kedua. juga
Marian Klühspies

11

Menggunakan Google Guava:

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

CharMatcher dapat dipasang dan cukup menarik untuk digunakan, misalnya Anda dapat melakukan hal berikut:

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

output == 123-456-789


Solusi yang sangat bagus (+1), tetapi mengalami masalah yang sama dengan yang lain: banyak karakter memenuhi syarat sebagai digit unicode, tidak hanya digit ascii. Kode ini akan mempertahankan semua karakter ini: unicode.org/cldr/utility/list-unicodeset.jsp?a=%5Cp%7Bdigit%7D
Sean Patrick Floyd

@seanizer: Maka ini akan menjadi CharMatcher.inRange yang lebih baik ('1', '9'). retainFrom ("123-456-789")
Emil

@Emil lebih mirip CharMatcher.inRange ('0', '9'), tetapi: ya
Sean Patrick Floyd

inRange adalah apa yang ada di balik CharMatcher.DIGIT; pastie.org/1252471 Ini hanya mempertimbangkan rentang nomor UTF akun, saya masih akan menganggap ini sebagai digit, karena dalam kenyataannya mereka, mereka sama sekali tidak dikodekan ASCII.
BjornS

Anda juga dapat menggunakan CharMatcher.JAVA_DIGIT untuk tujuan yang sama, yang hanya akan menerima angka sesuai Character.isDigit
BjornS

6

Gunakan persamaan reguler untuk memenuhi kebutuhan Anda.

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

Saya terinspirasi oleh kode Sean Patrick Floyd dan sedikit menulis ulang untuk kinerja maksimum yang saya dapatkan.

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

saya melakukan tes Kinerja untuk String yang sangat panjang dengan jumlah minimal dan hasilnya adalah:

  • Kode asli lebih lambat 25,5%
  • Pendekatan jambu biji lebih lambat 2,5-3 kali
  • Ekspresi reguler dengan D + adalah 3-3,5 kali lebih lambat
  • Ekspresi reguler dengan hanya D adalah 25+ kali lebih lambat

Tapi tergantung pada berapa lama string itu. Dengan string yang hanya berisi 6 angka jambu biji lebih lambat 50% dan regexp 1 kali lebih lambat


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

Output: 11



2

Saya telah menyelesaikan kode untuk nomor telepon +9 (987) 124124.

Karakter Unicode menempati 4 byte.

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

Kode:

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) ;
       }
       }
    }
 }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.