Estrai cifre da una stringa in Java


207

Ho un Stringoggetto Java . Devo estrarre solo cifre da esso. Faccio un esempio:

"123-456-789" Voglio "123456789"

Esiste una funzione di libreria che estrae solo cifre?

Grazie per le risposte Prima di provare questi, devo sapere se devo installare altri llibrari?

Risposte:


546

Puoi usare regex ed eliminare le non cifre.

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

6
bel codice funzione. Una ricerca lineare potrebbe essere più veloce ma penso che la tua abbia più senso.
kasten,

18
Immagino che tu possa sottovalutare qualsiasi cosa tu voglia sottovalutare (nessun sarcasmo previsto). Ma la mia opinione personale è: quando i grandi sviluppatori (e ne abbiamo molti qui) condividono alcuni dei loro consigli gratuitamente, allora lo onorerò e declasserò solo cose davvero orribili (controlla il mio profilo, la mia attuale il rapporto è 14xx contro 17 giù). Ma questa è la mia filosofia personale e tu sei libero di avere la tua.
Sean Patrick Floyd,

78
Questo non funzionerà se il tuo numero ha un punto decimale, rimuove anche il punto decimale. str = str.replaceAll("[^\\.0123456789]","");
Aravindan R,

2
Sebbene regex sia estremamente semplice e pulito da guardare, soffre di problemi di prestazioni e dovrebbe essere usato solo dove si dispone di una striscia unica (come l'invio di un modulo). Se stai elaborando molti dati, questa non è la strada da percorrere.
Brill Pappin,

2
e se hai bisogno di escludere qualcosa, come un punto decimale,(?!\\.)
azerafati,

49

Ecco una soluzione più dettagliata. Meno elegante, ma probabilmente più veloce:

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

Codice test:

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

Produzione:

0123456789

A proposito: non ho usato Character.isDigit (ch) perché accetta molti altri caratteri tranne 0 - 9.


4
È necessario fornire una dimensione al StringBuildercostruttore (come input.length()) per assicurarsi che non sia necessario riallocare. Non è necessario richiedere un Stringqui; CharSequencebasta. Inoltre, è possibile separare l'allocazione della StringBuilderdalla raccolta di non cifre scrivendo una funzione separata che accetta un CharSequenceinput e Appendableun'istanza come un accumulatore di output.
seh

1
@seh Sembra interessante ma piuttosto che commentare perché non creare la tua risposta con le estensioni?
RedYeti,

3
@RedYeti Lasciare questa risposta e aggiungere un commento è più onorevole poiché Sean riceve i voti allora. È anche molto più veloce criticare il codice degli altri che riscriverlo se hai fretta. Non punire Seh per aver dato un prezioso contributo, non ha dovuto aggiungere quei bocconcini utili e la tua risposta lo rende meno propenso a farlo la prossima volta.
KomodoDave,

2
Non sto "punendo" nessuno - questa è una completa interpretazione errata di ciò che stavo dicendo a @seh. Il mio punto era che i suoi commenti aggiungevano così tanto che valeva la pena e in effetti cambiarono così tanto che sentivo che era giustificata una sua risposta. Sono sicuro che Sean Patrick Floyd non si preoccupa dei complimenti solo per aiutare gli altri e sarebbe perfettamente felice di seh fornire la propria risposta. Stavo semplicemente incoraggiando Seh poiché sentivo che il suo contributo meritava maggiore visibilità. Come è possibile leggere il mio commento come qualsiasi altra cosa mi sconcerta completamente, ma mi scuso per averlo fatto se in qualche modo è successo.
RedYeti,

1
Mi piace come riprendono queste discussioni dopo aver dormito per un po '. Forse la cosa migliore da fare qui è per me modificare la risposta di Sean, aumentandola con i miei suggerimenti. In questo modo, Sean continuerà a ricevere il credito a meno che la risposta non passi allo stato wiki della comunità.
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();
}

Ho pensato di usare Character.isDigit () da solo, ma accetta anche alcuni caratteri che non sono 0-9 (vedi docs: download.oracle.com/javase/6/docs/api/java/lang/… )
Sean Patrick Floyd,

21

Utilizzando Google Guava:

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

AGGIORNARE:

L'utilizzo di CharMatcher precompilato può migliorare ulteriormente le prestazioni

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

3
Ora è Charmatcher.DIGITpredefinito.
Duncan McGregor,

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

Ciò ignorerà i punti decimali.

es: se hai un input come 445.3kgsarà l'output 445.3.


Ho "4.5 zi". non funziona perché mantiene il secondo. anche
Marian Klühspies il

11

Utilizzando Google Guava:

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

CharMatcher è plug-in e abbastanza interessante da usare, ad esempio puoi fare quanto segue:

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

uscita == 123-456-789


Soluzione molto bella (+1), ma soffre dello stesso problema di altri: molti caratteri si qualificano come cifre unicode, non solo le cifre ASCII. Questo codice conserverà tutti questi caratteri: unicode.org/cldr/utility/list-unicodeset.jsp?a=%5Cp%7Bdigit%7D
Sean Patrick Floyd,

@seanizer: Quindi sarà meglio CharMatcher.inRange ('1', '9'). retainFrom ("123-456-789")
Emil,

@Emil più come CharMatcher.inRange ('0', '9'), ma: sì
Sean Patrick Floyd,

inRange è ciò che sta dietro CharMatcher.DIGIT; pastie.org/1252471 Prende semplicemente in considerazione gli intervalli di numeri UTF attitudinali, li considererei comunque come cifre, poiché in realtà lo sono, semplicemente non sono codificati ASCII.
BjornS,

Puoi anche utilizzare CharMatcher.JAVA_DIGIT per lo stesso scopo, che accetta solo cifre come da Character.isDigit
BjornS

6

Usa l'espressione regolare per soddisfare le tue esigenze.

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

Mi sono ispirato al codice Sean Patrick Floyd e l'ho riscritto per ottenere le massime prestazioni.

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

faccio Performance test di stringa molto lunga con i numeri minimi e risultato è:

  • Il codice originale è più lento del 25,5%
  • L'approccio di Guava è 2,5-3 volte più lento
  • L'espressione regolare con D + è 3-3,5 volte più lenta
  • L'espressione regolare con solo D è più di 25 volte più lenta

A proposito, dipende da quanto è lunga quella stringa. Con una stringa che contiene solo 6 numeri, la guava è più lenta del 50% e regexp 1 volte più lenta


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

Uscita: 11



2

Ho finalizzato il codice per i numeri di telefono +9 (987) 124124.

I caratteri Unicode occupano 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

Codice:

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) ;
       }
       }
    }
 }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.