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.