Java'da bir dizeden rakamları ayıklayın


207

Bir Java'm var String nesnem var. Sadece rakamları çıkarmam gerekiyor. Bir örnek vereceğim:

"123-456-789" İstiyorum "123456789"

Yalnızca rakamları çıkaran bir kütüphane işlevi var mı?

Cevaplar için teşekkürler. Bunları denemeden önce başka llabra'ları kurmam gerekip gerekmediğini bilmem gerekir mi?

Yanıtlar:


546

Normal ifade kullanabilir ve rakam olmayanları silebilirsiniz.

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

6
güzel kısa kod. Doğrusal bir arama daha hızlı olabilir ama bence sizinkiler daha mantıklı.
kasten

18
Sanırım aşağılamak istediğiniz herhangi bir şeyi aşağıya vurabilirsiniz (alaycılık amaçlanmamıştır). Ama benim kişisel görüşüm: büyük geliştiriciler (ve burada birçoğumuz var) tavsiyelerinden bazılarını ücretsiz olarak paylaştıklarında, bundan onur duyacağım ve sadece gerçekten korkunç olan şeyleri aşağı indiriyorum (profilimi kontrol et, akımımı oranı 17xx yukarı 17 karşı). Ama bu benim kişisel felsefem ve kendi felsefesine sahip olmakta özgürsün.
Sean Patrick Floyd

78
Sayınızın ondalık noktası varsa, bu ondalık noktasını da kaldırır. str = str.replaceAll("[^\\.0123456789]","");
Aravindan R

2
Normal ifade bakmak son derece basit ve temiz olsa da, performans sorunlarından muzdariptir ve yalnızca bir kerelik şeridin olduğu yerde (form gönderme gibi) kullanılmalıdır. Çok fazla veri işliyorsanız, bu yol değildir.
Brill Pappin

2
ve ondalık (?!\\.)
ayırıcı

49

İşte daha ayrıntılı bir çözüm. Daha az zarif, ancak muhtemelen daha hızlı:

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

Test Kodu:

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

Çıktı:

0123456789

BTW: Character.isDigit (ch) kullanmadım çünkü 0-9 dışında birçok karakter kabul ediyor.


4
Yeniden tahsis edilmesi gerekmediğinden emin olmak için yapıcıya StringBuilder(örneğin input.length()) bir boyut sağlamalısınız. StringBurada talep etmenize gerek yok; CharSequenceyeterli. Ayrıca, StringBuildera CharSequencegirişini ve Appendableörneğini bir çıkış akümülatörü olarak kabul eden ayrı bir işlev yazarak, rakam olmayan koleksiyonundan ayırmayı ayırabilirsiniz .
seh

1
@seh Kulağa ilginç geliyor ama neden yorumlarla neden kendi cevabınızı oluşturmuyorsunuz?
RedYeti

3
@RedYeti Bu cevabın devam etmesine izin vermek ve yorum eklemek daha onurlu çünkü Sean o zamanlar oy kullanıyor. Aceleniz varsa başkalarının kodunu eleştirmek de yeniden yazmaktan çok daha hızlıdır. Değerli bir katkı yaptığı için seh'i cezalandırmayın, bu yararlı ipuçlarını eklemek zorunda değildi ve cevabınız bir dahaki sefere bunu yapma olasılığını azaltır.
KomodoDave

2
Ben kimseyi "cezalandırmıyorum" - bu @seh'e söylediklerimin tam olarak yanlış yorumlanması. Demek istediğim, yorumları çok değerli ve aslında o kadar değişti ki, kendi cevabını gerektirdiğini hissettim. Eminim Sean Patrick Floyd sadece başkalarına yardım eden kudoslarla ilgilenmez ve kendi cevabını vermekle çok mutlu olur. Katkısının daha fazla görünmeyi hak ettiğini hissettiğim için sadece seh'i cesaretlendiriyordum. Başka bir şey beni tamamen şaşırtıyor gibi yorumumu okumak nasıl mümkün ama bir şekilde yaparsa seh özür dilerim.
RedYeti

1
Bu tartışmaların bir süre uykuda kaldıktan sonra nasıl alındığını seviyorum. Belki de burada yapılacak en iyi şey, Sean'ın cevabını düzenlemek ve önerilerimle zenginleştirmek. Bu şekilde, cevap topluluk wiki statüsüne geçmedikçe Sean krediyi almaya devam edecektir.
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();
}

Character.isDigit () 'i kendim kullanmayı düşündüm, ancak 0-9 olmayan bazı karakterleri de kabul ediyor (bkz. Dokümanlar: download.oracle.com/javase/6/docs/api/java/lang/… )
Sean Patrick Floyd

21

Google Guava'yı kullanma:

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

GÜNCELLEME:

Önceden Hesaplanmış CharMatcher'ı kullanmak performansı daha da artırabilir

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

3
Şimdi Charmatcher.DIGITönceden tanımlanmış.
Duncan McGregor

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

Bu ondalık noktaları yok sayar.

örneğin: 445.3kgçıkış olarak bir giriş varsa 445.3.


"4.5 zi" var. çalışmıyor çünkü ikincisini koruyor. da
Marian Klühspies

11

Google Guava'yı kullanma:

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

CharMatcher takılabilir ve kullanımı oldukça ilginçtir, örneğin aşağıdakileri yapabilirsiniz:

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

çıktı == 123-456-789


Çok güzel bir çözüm (+1), ancak diğerleriyle aynı sorundan muzdarip: birçok karakter sadece ascii basamakları değil, unicode basamaklar olarak nitelendirilir. Bu kod şu karakterlerin tümünü koruyacak: unicode.org/cldr/utility/list-unicodeset.jsp?a=%5Cp%7Bdigit%7D
Sean Patrick Floyd

@seanizer: O zaman bu daha iyi olacak mı CharMatcher.inRange ('1', '9'). retainFrom ("123-456-789")
Emil

@Emil daha çok CharMatcher.inRange ('0', '9') gibi, ancak: evet
Sean Patrick Floyd

CharMatcher.DIGIT'in arkasında yatan inRange; pastie.org/1252471 Sadece dikkat çekici UTF sayı aralıklarını hesaba katar, yine de bunları rakam olarak kabul ederim, çünkü gerçekte onlar sadece ASCII kodlu değildir.
BjornS

CharMatcher.JAVA_DIGIT'i aynı amaçla da kullanabilirsiniz, bu da yalnızca Character.isDigit
BjornS

6

İhtiyacınıza uygun düzenli ifadeler kullanın.

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

Ben kod Sean Patrick Floyd esinlenerek ve biraz olsun maksimum performans için yeniden yazmak.

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

Minimum sayıda çok uzun String performans testi yapmak ve sonuç:

  • Orijinal kod% 25,5 daha yavaş
  • Guava yaklaşımı 2,5-3 kat daha yavaş
  • D + ile düzenli ifade 3-3,5 kat daha yavaştır
  • Sadece D ile düzenli ifade 25+ kat daha yavaştır

Btw bu dizginin uzunluğuna bağlıdır. Sadece 6 sayı içeren dize ile guava% 50 daha yavaş ve regexp 1 kat daha yavaş


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

Çıktı: 11



2

+9 (987) 124124 numaralı telefonların kodunu tamamladım.

Unicode karakterler 4 bayt kaplar.

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

Kod:

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) ;
       }
       }
    }
 }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.