it-swarm.com.de

Vergleich von Zeichen, bei denen Großbuchstaben ignoriert werden

Ich schreibe diese Codezeilen:

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++;
}

Ich möchte die Characters von zwei Strings vergleichen, die den Fall ignorieren. Die Verwendung von IgnoreCase funktioniert nicht. Das Hinzufügen von ASCII '65' funktioniert ebenfalls nicht. Wie mache ich das?

19
Arush Kamboj

Die Character -Klasse der Java-API bietet verschiedene Funktionen, die Sie verwenden können.

Sie können Ihr Zeichen auf beiden Seiten in Kleinbuchstaben konvertieren:

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

Es gibt auch Methoden, mit denen Sie überprüfen können, ob der Buchstabe in Groß- oder Kleinbuchstaben geschrieben ist:

Character.isUpperCase('P')
Character.isLowerCase('P') 
36
Shehzad

Mit toLowerCase können Sie eigentlich den Job nicht ganz richtig ausführen, entweder in einer Zeichenfolge oder in einem Zeichen. Das Problem ist, dass es unterschiedliche Glyphen in Groß- oder Kleinbuchstaben gibt. Abhängig davon, ob Sie Groß- oder Kleinbuchstaben verwenden, werden Ihre Glyphen möglicherweise beibehalten. Es ist nicht einmal klar, was Sie bedeuten wenn Sie sagen, dass zwei Varianten einer Kleinbuchstaben-Glyphe verglichen werden, ohne den Fall zu berücksichtigen: Sind sie oder sind sie nicht gleich? (Beachten Sie, dass es auch Glyphen mit Großbuchstaben gibt: \u01c5, \u01c8, \u01cb, \u01f2 oder Dž, Lj, Nj, Dz, aber alle hier vorgeschlagenen Methoden funktionieren auf diese, solange sie als ihre vollständigen Kleinbuchstaben gelten.)

Es gibt ein weiteres Problem bei der Verwendung von Char: Es gibt einige 80 Codepunkte, die nicht mit einer einzelnen Char dargestellt werden können, bei denen es sich um Groß-/Kleinschreibung (jeweils 40) handelt, zumindest so, wie es von Javas Codepunkt oben/unten erkannt wird. Sie müssen daher die Codepunkte abrufen und den Fall ändern.

Code-Punkte helfen jedoch nicht bei den unterschiedlichen Glyphen.

Wie dem auch sei, hier ist eine vollständige Liste der Glyphen, die aufgrund von Varianten problematisch sind, und zeigt, wie sie gegen 6 verschiedene Methoden ansetzen:

  1. Zeichen toLowerCase
  2. Zeichen toUpperCase
  3. String toLowerCase
  4. String toUpperCase
  5. String equalsIgnoreCase
  6. Zeichen toLowerCase(toUpperCase) (oder umgekehrt)

Für diese Methoden bedeutet S, dass die Varianten gleich behandelt werden, D, dass die Varianten als unterschiedlich behandelt werden.

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         Ṡ ṡ   ẛ   

Umso komplizierter ist, dass es keinen Weg gibt, die türkischen I richtig zu machen (d. H. Die gepunkteten Versionen unterscheiden sich von den nicht gepunkteten Versionen), es sei denn, Sie wissen, dass Sie Türkisch sprechen. Keine dieser Methoden führt zu korrektem Verhalten und kann nicht, es sei denn, Sie kennen das Gebietsschema (d. h. nicht-türkisch: i und I sind derselbe ignorierende Fall; türkisch nicht).

Im Allgemeinen erhalten Sie mit toUpperCase die näheste Annäherung, da Sie nur fünf Varianten (oder vier, nicht türkisch) haben.

Sie können auch versuchen, diese fünf problematischen Fälle gezielt abzufangen und toUpperCase(toLowerCase(c)) nur für sie aufzurufen. Wenn Sie Ihre Wachen sorgfältig auswählen (nur toUpperCase wenn c < 0x130 || c > 0x212B, dann arbeiten Sie die anderen Alternativen durch), können Sie für Zeichen im unteren Bereich nur einen Geschwindigkeitsnachlass von ~ 20% erhalten (im Vergleich zu ~ 4x, wenn Sie einzelne Zeichen in Zeichenfolgen und equalsIgnoreCase konvertieren.) und nur etwa eine 2-mal-Strafe, wenn Sie viel im Gefahrenbereich haben. Sie haben immer noch das Gebietsschema-Problem mit gepunkteten I, aber ansonsten sind Sie in einem anständigen Zustand. Wenn Sie equalsIgnoreCase für eine größere Zeichenfolge verwenden können, sollten Sie dies natürlich tun.

Hier ist ein Beispiel-Scala-Code, der die Aufgabe erfüllt:

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)
}
12
Rex Kerr

Sie können den Fall von String vor der Verwendung wie folgt ändern

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

Fahren Sie dann mit dem Ruhezustand fort.

7
Azhar Shaikh

Sie könnten beide Zeichen in Kleinbuchstaben setzen und dann vergleichen.

4
assylias

Sie müssen das türkische I-Problem beim Vergleich von Zeichen/Kleinbuchstaben/Großbuchstaben berücksichtigen:

Ich empfehle, in String zu konvertieren und toLowerCase mit invarianter Kultur zu verwenden (in den meisten Fällen zumindest).

public final static Gebietsschema InvariantLocale = neues Gebietsschema (leer, leer, leer); str.toLowerCase (InvariantLocale)

Siehe ähnliche C # string.ToLower () und string.ToLowerInvariant ()

Hinweis: Verwenden Sie keine String.equalsIgnoreCase http://nikolajlindberg.blogspot.co.il/2008/03/beware-of-Java-comparing-turkish.html

2
Dekel

Generische Methoden zum Vergleichen eines Zeichens an einer Position zwischen zwei Zeichenfolgen mit Groß- und Kleinschreibung.

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);
}

Funktionsaufruf

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

So macht es das JDK (angepasst von 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);
}

Ich vermute, das funktioniert auch für Türkisch?

0
Stefan Reich