如何比较基元类型中的字符忽略大小写

我正在编写以下代码行:

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

我想比较两个s的s忽略这种情况。简单地使用是行不通的。添加“65”值也不起作用。我该怎么做?CharacterStringIgnoreCaseASCII


答案 1

Java API 的 Character 类具有您可以使用的各种函数。

您可以在两侧将字符转换为小写:

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

还有一种方法可用于验证字母是大写还是小写:

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

答案 2

实际上不能在字符串或字符上使用 做正确的工作。问题在于,存在大写或小写的变体字形,并且根据您是大写还是小写,您的字形可能会保留,也可能不会保留。当你说小写字形的两个变体被比较为忽略大小写时,你甚至不清楚你的意思:它们是还是不一样?(请注意,也有混合大小写的字形:或 Dž、Lj、Nj、Dz,但这里建议的任何方法都可以使用,只要它们应与完全大写或完全小写变体相同。toLowerCase\u01c5, \u01c8, \u01cb, \u01f2

使用还有一个额外的问题:大约有80个代码点不能用单个代码点表示,它们是大写/小写变体(每个有40个),至少由Java的代码点上/下大小写检测到。因此,您需要获取代码点并更改这些代码点的大小写。CharChar

但是代码点对变体字形没有帮助。

无论如何,这里有一个完整的字形列表,这些字形由于变体而存在问题,显示了它们如何与6种变体方法相抗衡:

  1. 字符toLowerCase
  2. 字符toUpperCase
  3. 字符串toLowerCase
  4. 字符串toUpperCase
  5. 字符串equalsIgnoreCase
  6. 字符(反之亦然)toLowerCase(toUpperCase)

对于这些方法,意味着变体彼此被视为相同,意味着变体被视为彼此不同。SD

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

更复杂的是,除非您知道自己是土耳其语,否则没有办法使土耳其语I正确(即虚线版本与未标记的版本不同);这些方法都没有给出正确的行为,除非你知道区域设置(即非土耳其语:并且是相同的忽略大小写;土耳其语,不是)。iI

总体而言,使用可以为您提供最接近的近似值,因为您只有五个大写变体(或四个,不计算土耳其语)。toUpperCase

您也可以尝试专门拦截这五个麻烦的案例,并单独调用它们。如果您仔细选择警卫(只是如果,然后通过其他替代方案),对于低范围内的字符,您只能获得约20%的速度惩罚(如果您将单个字符转换为字符串和它们,则为~4倍),如果您在危险区域中有很多字符,则只能受到约2倍的惩罚。你仍然有点阵的区域设置问题,但除此之外,你的状态还不错。当然,如果你可以在一个更大的字符串上使用,你最好这样做。toUpperCase(toLowerCase(c))toUpperCasec < 0x130 || c > 0x212BequalsIgnoreCaseIequalsIgnoreCase

以下是完成这项工作的示例Scala代码:

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