2008-09-18 66 views

Trả lời

22

Chỉ cần kiểm tra xem một chữ cái có trong A-Z không vì nó không bao gồm các chữ cái có dấu hoặc chữ cái trong các bảng chữ cái khác.

tôi phát hiện ra rằng bạn có thể sử dụng lớp biểu thức chính quy cho 'thư Unicode', hoặc một trong các trường hợp nhạy cảm biến của nó:

string.matches("\\p{L}"); // Unicode letter 
string.matches("\\p{Lu}"); // Unicode upper-case letter 

Bạn cũng có thể làm điều này với Character lớp:

Character.isLetter(character); 

nhưng ít thuận tiện hơn nếu bạn cần kiểm tra nhiều hơn một chữ cái.

33

Character.isLetter() nhanh hơn nhiều so với string.matches(), vì string.matches() biên dịch Mẫu mới mỗi lần. Ngay cả bộ nhớ đệm mẫu, tôi nghĩ isLetter() vẫn sẽ đánh bại nó.


EDIT: Chỉ cần chạy qua này một lần nữa và nghĩ rằng tôi muốn cố gắng đưa ra một số con số thực tế. Đây là nỗ lực của tôi ở điểm chuẩn, kiểm tra cả ba phương pháp (matches() có và không có bộ nhớ đệm PatternCharacter.isLetter()). Tôi cũng đảm bảo rằng cả hai ký tự hợp lệ và không hợp lệ đều được kiểm tra, để không bị xáo trộn.

import java.util.regex.*; 

class TestLetter { 
    private static final Pattern ONE_CHAR_PATTERN = Pattern.compile("\\p{L}"); 
    private static final int NUM_TESTS = 10000000; 

    public static void main(String[] args) { 
     long start = System.nanoTime(); 
     int counter = 0; 
     for (int i = 0; i < NUM_TESTS; i++) { 
      if (testMatches(Character.toString((char) (i % 128)))) 
       counter++; 
     } 
     System.out.println(NUM_TESTS + " tests of Pattern.matches() took " + 
       (System.nanoTime()-start) + " ns."); 
     System.out.println("There were " + counter + "/" + NUM_TESTS + 
       " valid characters"); 
     /*********************************/ 
     start = System.nanoTime(); 
     counter = 0; 
     for (int i = 0; i < NUM_TESTS; i++) { 
      if (testCharacter(Character.toString((char) (i % 128)))) 
       counter++; 
     } 
     System.out.println(NUM_TESTS + " tests of isLetter() took " + 
       (System.nanoTime()-start) + " ns."); 
     System.out.println("There were " + counter + "/" + NUM_TESTS + 
       " valid characters"); 
     /*********************************/ 
     start = System.nanoTime(); 
     counter = 0; 
     for (int i = 0; i < NUM_TESTS; i++) { 
      if (testMatchesNoCache(Character.toString((char) (i % 128)))) 
       counter++; 
     } 
     System.out.println(NUM_TESTS + " tests of String.matches() took " + 
       (System.nanoTime()-start) + " ns."); 
     System.out.println("There were " + counter + "/" + NUM_TESTS + 
       " valid characters"); 
    } 

    private static boolean testMatches(final String c) { 
     return ONE_CHAR_PATTERN.matcher(c).matches(); 
    } 
    private static boolean testMatchesNoCache(final String c) { 
     return c.matches("\\p{L}"); 
    } 
    private static boolean testCharacter(final String c) { 
     return Character.isLetter(c.charAt(0)); 
    } 
} 

Và đầu ra của tôi:

10000000 tests of Pattern.matches() took 4325146672 ns. 
There were 4062500/10000000 valid characters 
10000000 tests of isLetter() took 546031201 ns. 
There were 4062500/10000000 valid characters 
10000000 tests of String.matches() took 11900205444 ns. 
There were 4062500/10000000 valid characters

Vì vậy, đó là hầu hết 8x tốt hơn, ngay cả với một cache Pattern. (Và uncached là gần 3x tồi tệ hơn so với lưu trữ.)

+3

Bạn nên sử dụng 'c.codePointAt (0)' thay vì 'c.charAt (0)' trong 'testCharacter()'; nếu không nó sẽ thất bại cho các nhân vật bên ngoài BMP. –

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