Come utilizzare le espressioni regolari in Android

Ho un numberDecimal EditText che voglio convalida utilizzando un’espressione regolare. In sede di convalida quello che voglio è:

  1. Prima del punto decimale, la massima cifra voglio entrare in tre e la cifra non dovrebbe iniziare con zero come 2,23,342, etc.
  2. Dopo il punto decimale, la massima cifra voglio entrare è uno come .1, .3, .6, etc.

In modo che il numero che mi permettono all’utente di accedere è come 2.1, 32.5, 444.8, 564.9, etc.

Ma nel mio codice, quello che succede è:

  1. Permette all’utente di inserire più di un numero di tre cifre prima del punto decimale come 3456, 4444, 5555 e dopo di che non mi permette di inserire un punto decimale dopo che.
  2. Mi permette di entrare 0 prima del punto decimale e l’inizio della cifra.

Quindi, perché questo accada, è qualcosa di sbagliato nel regolare l’espressione che ho usato? Se qualcuno sa, per favore aiutami a risolvere questo problema.

Codice che ho utilizzato:

weightEditText.addTextChangedListener(new TextWatcher() 
{           
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {               
    }           
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {            
    }           
    @Override
    public void afterTextChanged(Editable s) 
    {
        Pattern mPattern = Pattern.compile("^([1-9][0-9]{0,2})?(\\.[0-9]?)?$");

        Matcher matcher = mPattern.matcher(s.toString());               
        if(!matcher.find())
        {
            weightEditText.setText(); //Don't know what to place                   
        }
    }
});
InformationsquelleAutor AndroidDev | 2012-04-26

 

5 Replies
  1. 24

    Non c’è mai alcun punto in esame dest da solo in un InputFilter, che è ciò che è già presente in campo. Modificare l’espressione regolare partita contro source e sarebbe opportuno se si voleva solo controllare che certi personaggi sono stati accettati nel campo. Tuttavia, si desidera controllare la formattazione del campo, non solo per filtrare l’input di un carattere alla base. Questo è molto più complesso.

    Ogni volta che l’utente effettua una modifica al contenuto della tempEditText, il sistema chiama il tuo filtro filter metodo prima il cambiamento è in realtà fatta. Passa la corrente del contenuto di un campo e la proposta di modifica (che si possono inserire/aggiungere, eliminare o sostituire). La modifica è rappresentata da una fonte CharSequence source (i personaggi—se del caso—per essere aggiunto al campo), la gamma di indici di inizio e fine all’interno della sorgente (il range non è detto che tutte source), un Spanned dest (l’attuale contenuto del campo prima della modifica) e la gamma dstart e dend indici all’interno di dest che sono proposti per essere sostituito da quello indicato source gamma.

    Il lavoro di filter è quello di modificare il cambio (se necessario) e restituire un CharSequence per l’uso (nella sua interezza) in luogo di source (o null di andare avanti e di utilizzare source). Piuttosto che il controllo dest, come state facendo ora, sarà necessario verificare se il cambiamento si tradurrà in un campo accettabile. Per fare questo, avrete bisogno di una logica più complessa. (Si noti, in particolare, che il nuovo carattere(s) possono essere destinati a inserire da qualche altra parte che alla fine; inoltre, filter verrà chiamato quando l’utente è l’eliminazione di caratteri così come l’aggiunta di loro.)

    Può essere più facile da implementare un TextWatcher. In beforeTextChanged metodo, è possibile registrare il contenuto corrente e in afterTextChanged metodo, si può controllare (utilizzando un’espressione regolare) se i contenuti sono accettabili e, se non, ripristinare il prima-del-modificare il contenuto. (Assicuratevi, però, che il testo prima della modifica era accettabile. Se non lo è, sostituire con qualcosa di accettabile—come compensazione del campo. Altrimenti il tuo codice in un ciclo infinito, perché il TextWatcher sta per essere richiamato di nuovo quando si è corretto il contenuto del campo.)

    Hai anche un errore di espressione regolare: permette uno zero. Ecco una versione migliorata che consente di risolvere questo problema (e la rimuove una serie di inutili parentesi):

    "^([1-9][0-9]{0,2})?(\\.[0-9]?)?$"

    (Per inciso: è possibile utilizzare \\d invece di [0-9].)

    MODIFICA

    Ecco la mia modifica della modifica:

    weightEditText.addTextChangedListener(new TextWatcher() 
    {           
        private static final Pattern sPattern
            = Pattern.compile("^([1-9][0-9]{0,2})?(\\.[0-9]?)?$");
    
        private CharSequence mText;
    
        private boolean isValid(CharSequence s) {
            return sPattern.matcher(s).matches();
        }
    
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count){
        }           
    
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after){
            mText = isValid(s) ? new CharSequence(s) : "";
        }           
    
        @Override
        public void afterTextChanged(Editable s) 
        {
            if (!isValid(s))
            {
                weightEditText.setText(mText);
            }
            mText = null;
        }
    });
    • Ho modificato la mia risposta e farlo utilizzando TextWatcher. Ma non sono riuscito a trovare un idea di cosa scrivere in beforeTextChange metodo. u può, si prega di guardare la mia Cura rispondere e dirmi ciò che devo fare.
    • In primo luogo, spostare il vostro modello corrispondono a un altro metodo (chiamato, per esempio, isValid). Quindi dichiarare un campo nel TextWatcher per memorizzare il testo prima della modifica: class MyTextWatcher { private CharSequence mText; ... public void beforeTextChanged (CharSequence s, int start, int count, int after) { mText = isValid(s) ? new CharSequence(s) : ""; }. Infine, se il test ha esito negativo in afterTextChanged, chiamata weightEditText.setText(mText);. Inoltre, sempre insieme mText = null; prima di uscire afterTextChanged poiché il valore è ormai inutile.
    • Vorrei anche mPattern un static final campo; non c’è nessun punto nella compilazione di più di una volta.
    • Yeh il suo lavoro….grazie mille…un’ultima domanda, è possibile cambiare il mio modello in modo tale da non consentire l’immissione in decimale il punto di partenza della cifra.
    • Sicuro: "^([1-9][0-9]{0,2}(\\.[0-9]?)?)?$". (P. S. ho aggiornato la mia risposta con il codice di esempio. Sono contento che hai capito di lavoro.)
    • Ted Hopp Wow grande..funziona benissimo e di controllo per tutte la convalida..Ma voglio sapere effettivamente che cosa l’uso di ? c’…perché rimuovendo l’ ? risolvere il problema… può u si prega di spiegare a me ogni termine..
    • Non ho rimuoverlo. Mi sono spostato alla fine dell’intero modello. Il livello superiore modello è: ^(something)?$ – in altre parole, something è opzionale e una stringa vuota partite. Tra parentesi, something si scompone in due parti: [1-9][0-9]{0,2} — un non-zero cifra seguita da un massimo di 2 cifre e (\\.[0-9]?)? — un punto decimale seguita da una cifra opzionale, che è opzionale.
    • Pensile tastiera.
    • Cosa c’è di appendere la tastiera? C’è qualcosa nel logcat? È qualcosa di looping? Provare a impostare un punto di interruzione o due con il debugger per diagnosticare ciò che sta accadendo.

  2. 2

    Forse il mio attuazione consentirà a chiunque di:

        etRepeaterCallsign.addTextChangedListener(new TextWatcher() {
            private final Pattern sPattern
                    = Pattern.compile("^([A-Z]{0,2})?(\\d)?([A-Z-]{0,5})"); //^([1-9][0-9]{0,2})?(\\.[0-9]?)?$
    
            private CharSequence mText;
    
            private boolean isValid(CharSequence s) {
                return sPattern.matcher(s).matches();
            }
    
            @Override
            public void beforeTextChanged(CharSequence r, int start, int count,
                                          int after) {
                mText = r.toString();
            }
    
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                bIsEdit = true;
            }
            @Override
            public void afterTextChanged(Editable s) {
                etRepeaterCallsign.removeTextChangedListener(this);
    
                int iCursorPosition = etRepeaterCallsign.getSelectionStart();
                etRepeaterCallsign.setText("");
                if (isValid(s))
                    etRepeaterCallsign.append(s);
                else
                    etRepeaterCallsign.append(mText);
    
                etRepeaterCallsign.setSelection(iCursorPosition);
    
                etRepeaterCallsign.addTextChangedListener(this);
    
            }
        });
  3. 1

    Si può solo analizzare il numero e controllo che è < 1000 e 10*numero è un numero intero, mentre num non. Probabilmente sarebbe più leggibile troppo.

    • Mi potete spiegare con un esempio..sarà utile per me
  4. 0

    Si può provare qualcosa di simile a questo: ^[1-9][0-9]{0,2}(\\.\\d)?$. Questo dovrebbe corrispondere a qualsiasi numero che non inizia con 0 (^[1-9]) ed è seguita da più di due numeri ([0-9]{0,2}). L’espressione regolare consente anche per un ‘ eventuale valore decimale ((\\.\\d)?$).

    Detto questo, idealmente, si dovrebbe analizzare il valore di stringa di un double o float e fare ciò che mai convalide di cui avete bisogno per rendere l’uso effettivo valore numerico.

    Per analizzare la vostra string in un double valore, sarà necessario utilizzare il Doppio.parseDouble(String s) in questo modo: double myValue = Double.parseDouble(EditText.getText());

    • Ho usato ur modello. Ora non mi permette di digitare nulla nella EditText e una cosa se ho usato il singolo \ la mostra di errore. Sarà meglio se u mi mostra nel mio codice di esempio e per favore mi suggeriscono come posso analizzare la stringa di valore doppio, perché è memorizzato nel Attraversato dest variabile
    • Ho modificato la mia risposta. In Java è necessario fuga ` quindi è necessario avere a coppie, come per il cambiamento che ho fatto. Ho anche incluso un link per il JavaDoc su come si può analizzare una Stringa in un valore double.
    • Ho usato ur modello in mio codice come quello Schema.compilare(“(^[1-9])([0-9]{0,2})((\\.\\d)?$)”);. ora quello che succede è che non mi permette di digitare un numero nella casella di Modifica
    • Ma quando ho usato questo codice in java semplice progetto ed eseguire la console funziona benissimo e mostra l’errore quando inserisco il numero sbagliato. ma quando ho usato lo stesso codice e cercare di controllare l’errore nella EditText filtro di ingresso metodo non funziona perché questo accada.
    • Ho provato io stesso e ha funzionato per valori di stringa come 1, 2.1, 123.2 ma non per 02.1.
    • Si dovrebbe usare un debugger per vedere che cosa è in realtà essere passato e quando. Oltre a questo, non posso fare molto.
    • Yeh u r a destra se effettuo questa operazione su EditText.addTextChangedListener e mostra di errore in un altro TextView per numero errato invio funziona benissimo. La sua e ‘ qualcosa da fare sulla chiamata EditText.setFilter metodo..U può guardare il mio codice.
    • Non credo che sia una buona idea di accendere la Regex ogni volta che l’utente digita qualcosa nella casella di testo. Si dovrebbe fare la convalida una volta il pulsante di invio o il suo equivalente è premuto. Facendo il controllo con ogni pressione del tasto, molto probabilmente a causa di un errore di digitazione.
    • In realtà, lo so, ma la mia esigenza è solo. Devo verificare per la convalida quando l’utente digita nella casella di modifica solo. Cant utilizzato pulsante separato. C’è qualche modo per risolvere questo
    • Se si desidera convalidare i dati il più presto possibile, quindi, penso che si dovrebbe convalidare il campo di testo una volta che il fuoco è perso, non ogni volta che l’utente digita qualcosa.
    • Ma sarà che permette all’utente di digitare un numero sbagliato..anche perché la convalida è eseguire solo quando la si perde il focus dal EditText.
    • Che cosa si potrebbe fare è che se si perde il focus e il textfield non è valido, la visualizzazione di un messaggio come un’etichetta o qualcosa di simile e di ottenere il textfield messa a fuoco. Se si verificano ancora problemi, ti consiglierei di aprire una nuova domanda.

  5. 0

    Ho provato il tuo modello utilizzando il mio codice di esempio riportato di seguito. Funziona perfettamente, come 2.1, 32.5, 444.8, 564.9 etc.

    Il mio codice:

    public class WebPush extends Activity {  
        EditText editTxt;
        private TextView regresult;  
    
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main); 
    
            editTxt = (EditText) findViewById(R.id.editID);
            regresult = (TextView) findViewById(R.id.txtID);
    
            String urName = editTxt.getText().toString();
            editTxt.addTextChangedListener(new TextWatcher() {
    
                @Override
                public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
                }
    
                @Override
                public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,int arg3) {
                }       
    
                @Override
                public void afterTextChanged(Editable s) {
                    if (editTxt.getText().toString().matches("(^([0-9]{0,3})?)(\\.[0-9]{0,1})?$"))
                    {
                        regresult.setText("");
                    }
                    else
                    {
                        regresult.setText("invalid number");
                    }
                }
            });
        }
    }
    • Ma il mio caso non voglio mostrare errore in separata TextView. Io invece non permettere all’utente di inserire una cifra errata nella casella di Modifica. Intendo dire che se la cifra invio è corretta, solo che permetterà all’utente di immettere la cifra. Se è sbagliato, allora non permettere che l’utente tipo. Così do u know how che può essere fatto

Lascia un commento