2009-08-26 3 views
14

la mia prima domanda qui :-)
Ho fatto del mio meglio leggere le regole e cercare se la domanda fosse già stata posta prima.Java equalsIgnoreCase fallisce con ß ("Sharp S" usato in alfabeto tedesco)

Il codice seguente

String[] strings = {"cAsE", "\u00df"}; 
    for (String str : strings) { 
     System.out.println(str.equalsIgnoreCase(str.toLowerCase())); 
     System.out.println(str.equalsIgnoreCase(str.toUpperCase())); 
    } 

uscite vere 3 volte (= cAsE casi, causa = CASE; ß = ß) ma anche 1 falso (ß = SS!). Provato usando toLowerCase (Locale) ma non è stato d'aiuto.

Si tratta di un problema noto?

+1

Michael Kaplan ha scritto ampiamente sul carattere Sharp S tedesco. Le cose sono cambiate di recente e mi aspetto che le biblioteche stiano giocando un po 'di recupero. Un sacco di buone informazioni qui: http://blogs.msdn.com/michkap/archive/2008/05/15/8506679.aspx –

risposta

10

Fino a poco tempo fa, Unicode non ha definito una versione in maiuscolo di s-sharp. Non sono sicuro se l'ultima versione di Java 7 includa già questo nuovo personaggio e se lo gestisca correttamente. Suggerisco di fare un tentativo.

Il motivo per cui str.toLowerCase() non restituisce la stessa di str.toUpperCase().toLowerCase() è che Java sostituisce ß con SS, ma non c'è modo di tornare indietro, in modo da SS diventa ss e il confronto ha esito negativo.

Quindi, se è necessario livellare il caso, è necessario utilizzare str.toLowerCase(). In caso contrario, dovrebbe funzionare anche semplicemente chiamando equalsIgnoreCase() senza alcuna conversione superiore/inferiore.

+1

Anche se Java 7 supporta il nuovo carattere Unicode, "ß" .toUpperCase() deve ancora tornare "SS", dal momento che il maiuscolo "ß" è solo di interesse tipografico e non è realmente utilizzato in natura: http: //en.wikipedia.org/wiki/Capital_ß –

+0

Nel mio caso sto cercando di far corrispondere le stringhe di alcuni utenti con quelle predefinite (forse avrei dovuto menzionarlo nella domanda originale ...) Quindi il codice che ho dato qui come esempio è solo un ho eseguito un test per capire perché il mio codice originale non funzionava come previsto. Ovviamente esiste il metodo equalsIgnoreCase per salvarci dal cambiare il caso di entrambe le stringhe. In ogni caso, il concetto di "livellamento" è ciò che rende questa la mia risposta accettata :-) – targumon

0

Hm. Non so nulla della lingua tedesca, ma non sono sicuro di come mi rendo conto che i caratteri Unicode siano trattati come equivalenti a qualche espansione di lettere romane. Dovresti essere in grado di fare quanto segue?

myDictionary.put("glasses", new Bifocals()); 
myDictionary.get("glaßes"); 

Se avete i vostri druthers, myDictionary.get("glaßes") dovrebbe restituire qualcosa del Bifocals da prima. È legittimo?

+2

"ß" e "ss" non è equivalente. "ss" viene talvolta usato per scrivere "ß" quando quella lettera non è disponibile. Poiché non c'è maiuscolo "ß" (ok, ce n'è uno, ma è soprattutto una curiosità tipografica e non una lettera che viene usata nella realtà) sarà sempre scritto come "SS" in TUTTO MAIUSCOLO. Non è vero il contrario: "SS" .toLower() è decisamente "ss". –

+0

Ah, gotcha. Grazie per il chiarimento, Joachim. –

2

Aaron Digulla has it. Inoltre, non è significativo trasformare la stringa in assenza di dati locali. In inglese, la maiuscola di i è I, ma in turco è & # x0130;. String.compareIgnoreCase non prende in considerazione i dati delle impostazioni internazionali.

(Per inciso, si potrebbe voler esaminare normalization, o si finirà per chiedersi perché "& # x00E9;" uguale ("& # x0065; & # x0301;".) può restituire false . Motivo: uno è un combining sequence)

+0

è strano per me che la classe String ha 2 metodi ciascuno per toLowerCase & toUpperCase (uno senza parametri + uno che accetta un Locale) ma solo 1 metodo ciascuno per equalsIgnoreCase & compareToIgnoreCase se i ragazzi di Sun pensano che il * i metodi dei casi dovrebbero essere sensibili alle impostazioni internazionali, quindi mi aspetto che tutti li accettino anche. Grazie per il collegamento di normalizzazione, è un eccesso per il mio caso, ma perspicace lo stesso. – targumon

+0

@targumon: Si noti che in * all * locales '" ß ".toUpperCase (locale)' restituisce '" SS "', tuttavia a equalsIgnoreCase non interessa. È tutto rotto in qualche modo. – maaartinus

2

Unicode non ha definito una versione maiuscola di s-sharp questo è il punto esatto - in lingua tedesca non v'è alcuna possibilità di un brusco-s (. ß) essendo una capitale o la lettera iniziale di qualsiasi parola. quindi il suo non-senso discutere su una capitale ß ...