2012-04-19 12 views
16

estoy escribiendo estas líneas de código:Cómo comparar el carácter ignorando mayúsculas y minúsculas en los tipos primitivos

String name1 = fname.getText().toString(); 
String name2 = sname.getText().toString(); 
aru = 0; 

count1 = name1.length(); 
count2 = name2.length(); 
for (i = 0; i < count1; i++) 
{ 
    for (j = 0; j < count2; j++) 
    { 
     if (name1.charAt(i)==name2.charAt(j)) 
      aru++; 
    } 
    if(aru!=0) 
     aru++; 
} 

quiero comparar los Character s de dos String s ignorando el caso. Simplemente usando IgnoreCase no funciona. Agregar el valor '65' ASCII tampoco funciona. ¿Cómo hago esto?

+1

puede usar '' Character.toLowerCase' o Character.toUpperCase'to hacer todo a minúsculas o mayúsculas y compararlo. – idiottiger

+0

@idiottiger Eso funciona en el idioma inglés, pero no en todos los idiomas. –

Respuesta

32

La clase Character de la API de Java tiene varias funciones que puede usar.

Puede convertir el carbón en minúsculas en ambos lados:

Character.toLowerCase(name1.charAt(i)) == Character.toLowerCase(name2.charAt(j)) 

También hay métodos que puede utilizar para verificar si la letra es mayúscula o minúscula:

Character.isUpperCase('P') 
Character.isLowerCase('P') 
+0

Esto no funciona en todos los idiomas, por ejemplo, esto no funcionará para el idioma turco –

6

Puede cambiar el caso de la cadena antes de usarlo, como este

String name1 = fname.getText().toString().toLowerCase(); 
String name2 = sname.getText().toString().toLowerCase(); 

Luego continuar con la operación de reposo.

+0

Gracias ... ¡por mí! :) –

+3

se guarda del [problema locale turco] (http://mattryall.net/blog/2009/02/the-infamous-turkish-locale-bug). – axtavt

2

Tienes que considere el problema Turco I al comparar caracteres/minúsculas/mayúsculas:

Sugiero convertir a Cadena y usar toLowerCase con cultura invariable (en la mayoría de los casos al menos).

public final static Locale InvariantLocale = new Locale (Empty, Empty, Empty); str.toLowerCase (InvariantLocale)

ver similares C# string.ToLower() and string.ToLowerInvariant()

Nota: No utilice String.equalsIgnoreCase http://nikolajlindberg.blogspot.co.il/2008/03/beware-of-java-comparing-turkish.html

10

Puede no realmente hacer el trabajo bastante bien con toLowerCase, ya sea en una cadena o en un personaje. El problema es que hay glifos variantes en mayúscula o minúscula, y dependiendo de si mayúsculas o minúsculas sus glifos pueden conservarse o no. Ni siquiera está claro lo que significa cuando dice que se comparan dos variantes de un glifo en minúscula ignorando caso: ¿son o no son lo mismo? (Tenga en cuenta que también hay glifos de mayúsculas y minúsculas: \u01c5, \u01c8, \u01cb, \u01f2 o Dž, Lj, Dz, pero cualquier método sugerido aquí funcionará en esos casos, siempre que se consideren igual que sus variantes de mayúscula o minúscula completa).

Existe un problema adicional con el uso de Char: hay unos 80 puntos de código no representables con un solo Char que son variantes de mayúsculas/minúsculas (40 de cada), al menos detectadas por el código de Java mayúsculas/minúsculas . Por lo tanto, necesita obtener los puntos de código y cambiar el caso en estos.

Pero los puntos de código no ayudan con los glifos variantes.

De todos modos, aquí está una lista completa de los glifos que son problemáticos debido a las variantes, mostrando cómo les va en contra de 6 métodos de variación de

  1. carácter toLowerCase
  2. Carácter toUpperCase
  3. cadena toLowerCase
  4. cadena toUpperCase
  5. cadena equalsIgnoreCase
  6. Carácter toLowerCase(toUpperCase) (o viceversa)

Para estos métodos, S significa que las variantes se tratan de la misma como los demás, D significa que las variantes se tratan como diferentes entre sí.

Behavior  Unicode        Glyphs 
=========== ================================== ========= 
1 2 3 4 5 6 Upper Lower Var Up Var Lo Vr Lo2 U L u l l2 
- - - - - - ------ ------ ------ ------ ------ - - - - - 
D D D D S S \u0049 \u0069 \u0130 \u0131   I i İ ı 
S D S D S S \u004b \u006b \u212a    K k K  
D S D S S S \u0053 \u0073  \u017f   S s ſ 
D S D S S S \u039c \u03bc  \u00b5   Μ μ µ 
S D S D S S \u00c5 \u00e5 \u212b    Å å Å  
D S D S S S \u0399 \u03b9  \u0345 \u1fbe Ι ι ͅ ι 
D S D S S S \u0392 \u03b2  \u03d0   Β β ϐ 
D S D S S S \u0395 \u03b5  \u03f5   Ε ε ϵ 
D D D D S S \u0398 \u03b8 \u03f4 \u03d1   Θ θ ϴ ϑ 
D S D S S S \u039a \u03ba  \u03f0   Κ κ ϰ 
D S D S S S \u03a0 \u03c0  \u03d6   Π π ϖ 
D S D S S S \u03a1 \u03c1  \u03f1   Ρ ρ ϱ 
D S D S S S \u03a3 \u03c3  \u03c2   Σ σ ς 
D S D S S S \u03a6 \u03c6  \u03d5   Φ φ ϕ 
S D S D S S \u03a9 \u03c9 \u2126    Ω ω Ω  
D S D S S S \u1e60 \u1e61  \u1e9b   Ṡ ṡ ẛ 

Para complicar aún más este es que no hay manera de conseguir el derecho de Turquía I (es decir, las versiones de puntos son diferentes de las versiones sin punto) a menos que usted sabe que está en Turquía; ninguno de estos métodos dan un comportamiento correcto y no puede menos que conozca la configuración regional (es decir, no turco: i y I son el mismo caso ignorando; turca, no).

En general, usar toUpperCase le da la aproximación más aproximada, ya que solo tiene cinco variantes en mayúscula (o cuatro, sin contar el turco).

También puede tratar de interceptar específicamente esos cinco casos problemáticos y llame toUpperCase(toLowerCase(c)) en ellos solos. Si usted elige sus guardias con cuidado (solo toUpperCase si c < 0x130 || c > 0x212B, a continuación, trabajar a través de las otras alternativas) se puede obtener sólo un 20% de penalización ~ velocidad para los caracteres en el rango bajo (en comparación con ~ 4x si convierte los caracteres individuales de cuerdas y equalsIgnoreCase ellos) y solo una penalización de 2x si tienes mucho en la zona de peligro. Todavía tiene el problema de configuración regional con I con puntos, pero de lo contrario se encuentra en una buena forma. Por supuesto, si puede usar equalsIgnoreCase en una cadena más grande, será mejor que lo haga.

Aquí es código Scala muestra que hace el trabajo:

def elevateCase(c: Char): Char = { 
    if (c < 0x130 || c > 0x212B) Character.toUpperCase(c) 
    else if (c == 0x130 || c == 0x3F4 || c == 0x2126 || c >= 0x212A) 
    Character.toUpperCase(Character.toLowerCase(c)) 
    else Character.toUpperCase(c) 
} 
0

métodos genéricos para comparar un char en una posición entre 2 cadenas con ignorar caso.

public static boolean isEqualIngoreCase(char one, char two){ 
    return Character.toLowerCase(one)==Character .toLowerCase(two); 
} 

public static boolean isEqualStringCharIgnoreCase(String one, String two, int position){ 
    char oneChar = one.charAt(position); 
    char twoChar = two.charAt(position); 
    return isEqualIngoreCase(oneChar, twoChar); 
} 

llamada Función

boolean isFirstCharEqual = isEqualStringCharIgnoreCase("abc", "ABC", 0) 
0

Así es como el JDK lo hace (adaptado de OpenJDK 8, String.java/regionMatches):

static boolean charactersEqualIgnoringCase(char c1, char c2) { 
    if (c1 == c2) return true; 

    // If characters don't match but case may be ignored, 
    // try converting both characters to uppercase. 
    char u1 = Character.toUpperCase(c1); 
    char u2 = Character.toUpperCase(c2); 
    if (u1 == u2) return true; 

    // Unfortunately, conversion to uppercase does not work properly 
    // for the Georgian alphabet, which has strange rules about case 
    // conversion. So we need to make one last check before 
    // exiting. 
    return Character.toLowerCase(u1) == Character.toLowerCase(u2); 
} 

supongo que las obras de turco también?

Cuestiones relacionadas