2015-06-07 17 views
16

Ho una stringa variabile che potrebbe contenere qualsiasi carattere Unicode. Uno di questi caratteri unicode è il han .Come faccio a confrontare ciascun carattere di una stringa tenendo conto dei caratteri con lunghezza> 1?

Il fatto è che questo carattere "han" ha "".length() == 2 ma è scritto nella stringa come un singolo carattere.

Considerando il seguente codice, come dovrei scorrere tutti i caratteri e confrontarli considerando il fatto che potrebbe contenere un carattere con lunghezza maggiore di 1?

for (int i = 0; i < string.length(); i++) { 
    char character = string.charAt(i); 
    if (character == '') { 
     // Fail, it interprets as 2 chars =/ 
    } 
} 

EDIT:
questa domanda non è un duplicato. Questo chiede come iterare per ogni carattere di una stringa considerando i caratteri che contiene .length() > 1 (carattere non come tipo char ma come rappresentazione di un simbolo scritto). Questa domanda non richiede conoscenze precedenti su come iterare su punti di codice unicode di una stringa Java, anche se una risposta che menziona potrebbe anche essere corretta.

+5

http://stackoverflow.com/questions/1527856/how-can-i-iterate-through-the-unicode-codepoints-of-a-java-string – user2357112

+0

Devo usare "symbol" invece di "character" in questa domanda per chiarire? –

risposta

11
int hanCodePoint = "".codePointAt(0); 
for (int i = 0; i < string.length();) { 
    int currentCodePoint = string.codePointAt(i); 
    if (currentCodePoint == hanCodePoint) { 
     // do something here. 
    } 
    i += Character.charCount(currentCodePoint); 
} 
+0

Non c'è modo di confrontarsi con le virgolette singole ''''? –

+2

sfortunatamente, no. '' è un carattere Unicode valido, ma non è esprimibile come un singolo 'char' Java, che è ciò che sarebbe necessario essere in grado di metterlo tra virgolette singole. Se ci provi, noterai che non sarai nemmeno in grado di compilarlo. Un java 'char' può rappresentare solo i caratteri Unicode fino al punto codice 65.535. Passato, hai bisogno di 2 surrogati 'char's per rappresentare il personaggio, o semplicemente usa un' String'. Molto fastidioso, sono d'accordo. – sstan

+0

Infatti, non può compilare. Grazie uomo! –

-4

Un carattere ASCII prende la metà dell'importo di un char Unicode, quindi è logico che il carattere han sia di lunghezza 2. Non è un carattere ASCII, né una lettera Unicode. Se fosse il secondo caso, la lettera verrebbe visualizzata correttamente.

+0

Un carattere ASCII in Unicode ha le stesse dimensioni di ASCII. Quello a cui ti stai riferendo maggiormente sono i caratteri Unicode multi-byte. – Makoto

+0

Mi dispiace, hai ragione – user9138

9

I metodi String.charAt e String.length trattano una stringa come una sequenza di unità di codice UTF-16. Si desidera trattare la stringa come punti codice Unicode.

Osservare i metodi "punto codice" nella API String:

  • codePointAt(int index) restituisce la (32 bit) punto di codice in un dato indice codice unità
  • offsetByCodePoints(int index, int codePointOffset) restituisce l'indice codice unità corrispondente ai punti codice codePointOffset dall'unità di codice allo index.
  • codePointCount(int beginIndex, int endIndex) conta i punti di codice tra due indici code-unit.

L'indicizzazione della stringa in base all'indice del codice è un po 'complicata, soprattutto se la stringa è lunga e si desidera eseguire in modo efficiente. Tuttavia, è una possibilità, anche se il codice è piuttosto ingombrante.

@ sstan's answer è una soluzione.

3

Questo sarà più semplice se si trattano sia la stringa ed i dati che stai cercando come String s. Se avete solo bisogno di verificare la presenza di quel personaggio:

if (string.contains("") { 
    // do something here. 
} 

Se è specificamente necessario l'indice in cui sembra che il personaggio:

int i = string.indexOf(""); 
if (i >= 0) { 
    // do something with i here. 
} 

E se si ha realmente bisogno di scorrere attraverso ogni punto di codice, vedi How can I iterate through the unicode codepoints of a Java String?.

+0

Qual è il costo del tempo usando '.contains' o' .indexOf' per tutti i caratteri che sto testando? Sto cercando un approccio più generico invece di usare '.contains' o' .indexOf' solo per caratteri con 'length> 1'. –

+0

Questa risposta sembra essere più vicina alla domanda piuttosto che iterare su punti di codice unicode, pur sacrificando alcune prestazioni. –