2012-02-29 25 views
11

Ho un campo di input quali è localizzata . Ho bisogno di aggiungere una convalida usando una regex che deve contenere solo alfabeti e numeri. Avrei potuto usare [a-z0-9] se stavo usando solo l'inglese.Regex per la validazione alfabetici e numeri nella stringa localizzata

A partire da ora, sto usando il metodo (sì, sto iterando attraverso ogni carattere) per filtrare gli alfabeti presenti in varie lingue.

Ci sono modi migliori per farlo? Qualsiasi regex o altre librerie disponibili per questo?

+0

Quindi vuoi gestire anche lingue diverse dall'inglese, giusto? – Lukasz

+0

alla ricerca di una soluzione generica ** compreso inglese ** – ManuPK

+1

Secondo [this] (http://stackoverflow.com/questions/2392194/how-to-match-the-international-alphabet-english-az-non-english -with-a-regu) post il '\ w' funziona anche nelle espressioni regolari di perl sui caratteri unicode, non so se è così nelle regex di java. – user1227804

risposta

18

Dal momento che Java 7 è possibile utilizzare Pattern.UNICODE_CHARACTER_CLASS

String s = "Müller"; 

Pattern p = Pattern.compile("^\\w+$", Pattern.UNICODE_CHARACTER_CLASS); 
Matcher m = p.matcher(s); 
if (m.find()) { 
    System.out.println(m.group()); 
} else { 
    System.out.println("not found"); 
} 

con fuori l'opzione non riconoscerà la parola "Müller", ma utilizzando Pattern.UNICODE_CHARACTER_CLASS

Abilita la versione Unicode di classi di caratteri predefiniti e Classi di caratteri POSIX.

Vedi here for more details

Si può anche avere uno sguardo here for more Unicode information in Java 7.

e qui in regular-expression.info una panoramica sulle Unicode script, le proprietà e blocchi.

See here a famous answer from tchrist circa le avvertenze di regex in Java, tra cui una versione aggiornata di ciò che è cambiato con Java 7 (di sarà in Java 8)

+0

Ovviamente questo corrisponderà anche ai trattini bassi e ad altri segni di punteggiatura. –

+0

@TimPietzcker è vero, se questo è importante, la tua risposta sarebbe la scelta migliore per l'OP (+1 per te) – stema

+0

@TimPietzcker Sotto 'UNICODE_CHARACTER_CLASS', le cosiddette classi POSIX corrispondono anche per [UTS n. 18 Annex C ] (http://unicode.org/reports/tr18/#Compatibility_Properties); cioè, '\ p {alpha}' diventa - se e solo se compilato sotto il flag di compilazione 'Pattern' - esattamente uguale alla proprietà Unicode' Alphabetic = True', che è a sua volta un po 'complicata ma abbastanza utile, e che fa non includere la punteggiatura del connettore. Mi dispiace per la frase run-on. :) – tchrist

8
boolean foundMatch = name.matches("[\\p{L}\\p{Nd}]*"); 

dovrebbe funzionare.

[\p{L}\p{Nd}] corrisponde a un carattere che è o una lettera Unicode o cifre. Il metodo regex .matches() assicura che l'intera stringa corrisponda al modello.

+1

Altre possibili categorie Unicode (ad esempio 'L' o' N') possono essere trovate [qui] (http://www.fileformat.info/info/unicode/category/index.htm). – beerbajay

+0

Non hai bisogno di parentesi graffe per le 7 categorie principali. Potrebbe piacerti anche '\ pM', quindi' [\ pL \ pM \ pN] '. Nota che questa è già una definizione più ampia di '\ p {Alphabetic}', perché include tutti i segni, non solo alcuni di essi. Ciò lo avvicina alla proprietà '\ p {word}' usata per gli identificatori del programma, che per [UTS # 18 Annec C] (http://unicode.org/reports/tr18/#Compatibility_Properties) è '[\ p { alpha} \ p {gc = Contrassegna} \ p {gc = Cifra} \ p {gc = Pc}] ', dove' \ p {alpha} 'è complicato, ma in pratica seleziona solo alcuni segni. – tchrist

+0

@TimPietzcker Tieni duro: il tuo test booleano è sbagliato. Tutte le stringhe possibili corrispondono a zero o più ripetizioni di qualsiasi cosa. Non penso che tu voglia quella stella. Inoltre, come commentato altrove, anche se probabilmente lo vuoi, '\ pN' è più che solo cifre; '\ p {Nd}' sono solo cifre decimali senza numeri romani, frazioni volgari o sub e superscripts, ecc. Basta chiamare '\ pN' qualsiasi numero numerico, non una qualsiasi cifra, e avrai ragione. – tchrist

1

Alcune persone, quando di fronte a un problema, pensa "Lo so, Userò le espressioni regolari . " Ora hanno due problemi.

- Jamie Zawinksi

lo dico per scherzo, ma scorrendo la stringa come si sta facendo avrà prestazioni di runtime almeno buono come qualsiasi regex - non c'è modo una regex può fare quello che vuoi più veloce; e tu non hai il sovraccarico di compilare un modello in primo luogo.

Quindi, fintanto che:

  • la convalida non ha bisogno di fare altro regex-simile (nulla è stato menzionato nella questione)
  • l'intenzione del codice loop attraverso la stringa è chiaro (e in caso contrario, refactoring fino a quando non lo è)

allora perché sostituirlo con una regex solo perché è possibile?

+2

Sarebbe interessante eseguire il backup di questa affermazione mediante misure. –

+0

+1 ben si può essere d'accordo o in disaccordo, è davvero un link interessante! – ManuPK

+0

@Tim: non hai nemmeno bisogno di misurazioni. A meno che non si utilizzi il calcolo quantico, non è possibile verificare che tutti i caratteri di un elenco di caratteri (ovvero una stringa) siano lettere o cifre senza visitare ciascun carattere e si fermino non appena ne trovi uno che non lo è. Poiché questo è ciò che fa il codice personalizzato, è la quantità minima di lavoro possibile. I regex non sono magici. –

Problemi correlati