2012-04-19 22 views
16

Tôi viết những dòng mã:Làm thế nào để so sánh nhân vật bỏ qua trường hợp trong các loại nguyên thủy

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

tôi muốn so sánh các Character s của hai String s bỏ qua như vậy. Chỉ cần sử dụng IgnoreCase không hoạt động. Thêm giá trị '65' ASCII không hoạt động. Làm thế nào để tôi làm điều này?

+1

bạn có thể sử dụng 'Character.toLowerCase' hoặc' Character.toUpperCase' để chuyển tất cả thành chữ thường hoặc chữ thường và so sánh nó. – idiottiger

+0

@idiottiger Làm việc bằng tiếng Anh, nhưng không phải bằng mọi ngôn ngữ. –

Trả lời

32

Lớp Java API Character có các chức năng khác nhau mà bạn có thể sử dụng.

Bạn có thể chuyển đổi char của bạn thành chữ thường ở cả hai phía:

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

Ngoài ra còn có một phương pháp bạn có thể sử dụng để xác minh nếu bức thư được viết hoa hay chữ thường:

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

Điều này không hoạt động ở mọi ngôn ngữ, ví dụ, điều này sẽ không thành công cho tiếng Thổ Nhĩ Kỳ –

6

Bạn có thể thay đổi trường hợp của chuỗi trước khi sử dụng nó, như thế này

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

Sau đó tiếp tục với hoạt động nghỉ ngơi.

+0

Xin cảm ơn..đã cho tôi! :) –

+3

Hãy coi chừng [vấn đề ngôn ngữ Thổ Nhĩ Kỳ] (http://mattryall.net/blog/2009/02/the-infamous-turkish-locale-bug). – axtavt

2

Bạn có thể put both chars in lower case và sau đó so sánh chúng.

+0

: P vâng tôi có thể..sry .. –

+1

Sai, do vấn đề Thổ Nhĩ Kỳ: https://stackoverflow.com/a/13550932/14731 – Gili

2

Bạn phải xem xét vấn đề tiếng Thổ Nhĩ Kỳ I khi so sánh các ký tự/số thấp hơn/uppercasing:

Tôi đề nghị chuyển thành Chuỗi và sử dụng toLowerCase với văn hóa bất biến (trong hầu hết các trường hợp ít nhất).

tĩnh cuối cùng công khai Locale InvariantLocale = new Locale (Empty, Empty, Empty); str.toLowerCase (InvariantLocale)

Xem tương tự C# string.ToLower() and string.ToLowerInvariant()

Lưu ý: Không sử dụng String.equalsIgnoreCase http://nikolajlindberg.blogspot.co.il/2008/03/beware-of-java-comparing-turkish.html

10

Bạn có thể không thực sự thực hiện công việc khá đúng với toLowerCase, hoặc trên một chuỗi hoặc trong một ký tự. Vấn đề là có glyphs biến thể trong cả hai trường hợp trên hoặc dưới, và tùy thuộc vào việc bạn viết hoa hoặc viết thường glyphs của bạn có thể hoặc có thể không được bảo tồn. Nó thậm chí không rõ ràng những gì bạn có nghĩa là khi bạn nói rằng hai biến thể của một glyph trường hợp thấp hơn được so sánh bỏ qua trường hợp: là họ hoặc là họ không giống nhau? (Lưu ý rằng cũng có glyphs hỗn hợp: \u01c5, \u01c8, \u01cb, \u01f2 hoặc Dž, Lj, Nj, Dz, nhưng bất kỳ phương pháp nào được đề xuất ở đây sẽ hoạt động trên những điều đó miễn là chúng được tính giống như biến thể hoàn toàn trên hoặc dưới hoàn toàn của chúng.)

Có một vấn đề khác khi sử dụng Char: có một số 80 điểm mã không thể đại diện với một Char là các biến thể chữ hoa/chữ thường (40 của mỗi trường), ít nhất là được phát hiện bởi mã trên/dưới của mã Java . Do đó, bạn cần lấy các điểm mã và thay đổi trường hợp trên các mã này.

Nhưng các điểm mã không hỗ trợ biến thể glyph.

Dù sao, đây là một danh sách đầy đủ của các ký hiệu là vấn đề do các biến thể, cho thấy làm thế nào họ giá vé so với 6 phương pháp biến thể:

  1. Character toLowerCase
  2. Character toUpperCase
  3. Chuỗi toLowerCase
  4. Chuỗi toUpperCase
  5. Chuỗi equalsIgnoreCase
  6. Character toLowerCase(toUpperCase) (hoặc ngược lại)

Đối với phương pháp này, S có nghĩa là các biến thể được đối xử giống như nhau, D nghĩa các biến thể được coi là khác nhau từ mỗi khác.

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

Phức tạp hơn nữa là không có cách nào để nhận được quyền Thổ Nhĩ Kỳ I (tức là các phiên bản chấm khác với phiên bản chưa phân loại) trừ khi bạn biết bạn đang ở Thổ Nhĩ Kỳ; không có phương pháp nào trong số những phương pháp này đưa ra hành vi đúng và không thể trừ khi bạn biết ngôn ngữ (ví dụ: không phải Thổ Nhĩ Kỳ: iI là trường hợp bỏ qua tương tự; tiếng Thổ Nhĩ Kỳ, không).

Nhìn chung, sử dụng toUpperCase cung cấp cho bạn xấp xỉ gần nhất, vì bạn chỉ có năm biến thể chữ hoa (hoặc bốn, không tính tiếng Thổ Nhĩ Kỳ).

Bạn cũng có thể cố gắng chặn riêng năm trường hợp phiền hà đó và gọi toUpperCase(toLowerCase(c)) trên chúng một mình. Nếu bạn chọn bảo vệ cẩn thận (chỉ toUpperCase nếu c < 0x130 || c > 0x212B, sau đó làm việc thông qua các lựa chọn thay thế khác), bạn chỉ có thể nhận được hình phạt tốc độ ~ 20% cho các ký tự trong phạm vi thấp (so với ~ 4x nếu bạn chuyển đổi các ký tự đơn thành chuỗi và equalsIgnoreCase chúng) và chỉ khoảng một hình phạt 2x nếu bạn có rất nhiều trong khu vực nguy hiểm. Bạn vẫn có vấn đề về miền địa phương với chấm chấm I, nhưng nếu không bạn có hình dạng tốt. Tất nhiên nếu bạn có thể sử dụng equalsIgnoreCase trên một chuỗi lớn hơn, bạn nên làm điều đó.

Đây là mẫu mã Scala mà không được công việc:

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

phương pháp Generic để so sánh một char ở vị trí giữa 2 chuỗi với bỏ qua trường hợp.

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

Chức năng gọi

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

Đây là cách JDK nó (chuyển thể từ 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); 
} 

Tôi cho rằng công trình cho Thổ Nhĩ Kỳ cũng?

Các vấn đề liên quan