32

我正在编写这些代码行:

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

我想比较Character两个String忽略大小写的 s 。简单地使用IgnoreCase是行不通的。添加“65”ASCII值也不起作用。我该怎么做呢?

4

6 回答 6

57

CharacterJava API 类具有您可以使用的各种功能。

您可以在两边将您的 char 转换为小写:

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

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

Character.isUpperCase('P')
Character.isLowerCase('P') 
于 2012-04-19T07:20:48.437 回答
16

无论是在字符串上还是在字符上,您实际上都不能完全正确地完成这项工作。toLowerCase问题是大写或小写都有变体字形,并且取决于您是大写还是小写,您的字形可能会或可能不会被保留。当您说忽略大小写比较小写字形的两个变体时,甚至不清楚您的意思是:它们是相同的还是不相同的?(请注意,也有混合大小写的字形:\u01c5, \u01c8, \u01cb, \u01f2或Dž、Lj、Nj、Dz,但此处建议的任何方法都适用于这些字形,只要它们应该与它们的完全大写或完全小写变体相同。)

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

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

无论如何,这里有一个完整的由于变体而有问题的字形列表,展示了它们在 6 种变体方法中的表现:

  1. 特点toLowerCase
  2. 特点toUpperCase
  3. 细绳toLowerCase
  4. 细绳toUpperCase
  5. 细绳equalsIgnoreCase
  6. 字符toLowerCase(toUpperCase)(反之亦然)

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

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 是正确的(即带点的版本与不带点的版本不同)。这些方法都不能提供正确的行为,除非您知道语言环境(即非土耳其语:i并且I是相同的忽略大小写;土耳其语,不是)。

总体而言, usingtoUpperCase为您提供了最接近的近似值,因为您只有五个大写变体(或四个,不包括土耳其语)。

你也可以尝试专门拦截这五个麻烦的案例,toUpperCase(toLowerCase(c))单独调用。如果你仔细选择你的守卫(toUpperCase如果c < 0x130 || c > 0x212B,然后通过其他替代方案),你只能在低范围内的字符上获得约 20% 的速度损失(相比之下,如果你将单个字符转换为字符串和equalsIgnoreCase它们,则为约 4 倍)和如果您在危险区域中有很多东西,则只有大约 2 倍的惩罚。你仍然有 dotted 的语言环境问题I,但除此之外你的状态还不错。当然,如果你可以equalsIgnoreCase在更大的字符串上使用,你最好这样做。

这是完成这项工作的示例 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)
}
于 2015-03-06T09:45:30.473 回答
9

您可以在使用之前更改 String 的大小写,就像这样

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

然后继续休息操作。

于 2012-04-19T07:10:53.810 回答
3

在比较字符/小写/大写时,您必须考虑土耳其语 I 问题:

我建议转换为字符串并使用具有不变文化的 toLowerCase(至少在大多数情况下)。

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

查看类似的 C# string.ToLower() 和 string.ToLowerInvariant()

注意:不要使用 String.equalsIgnoreCase http://nikolajlindberg.blogspot.co.il/2008/03/beware-of-java-comparing-turkish.html

于 2012-11-25T12:18:33.993 回答
3

这就是 JDK 的工作方式(改编自 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);
}

我想这也适用于土耳其语。

于 2017-10-11T16:05:50.020 回答
1

将 2 个字符串之间某个位置的字符与忽略大小写进行比较的通用方法。

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

函数调用

boolean isFirstCharEqual = isEqualStringCharIgnoreCase("abc", "ABC", 0)
于 2016-10-13T08:43:05.547 回答