2008-09-18 22 views

cevap

22

Sadece bir harf A-Z içerip içermediğini kontrol edin, çünkü bu, diğer alfabelerde aksan veya harf içeren harfler içermez.

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

Ayrıca Karakter ile yapabilirsiniz sınıfı:

Ben onun küçük harfe duyarlı varyasyonlarının birini 'Unicode harfi' için düzenli ifade sınıfını kullanabilir veya öğrendim

Ancak, birden fazla harfi kontrol etmeniz gerekiyorsa bu daha az kullanışlıdır.

33

Karakter.isLetter(), string.matches() işlevinden çok daha hızlıdır, çünkü string.matches() her seferinde yeni bir Pattern'i derler. Kalıbın önbelleğe alınması bile, bence Letter() hala onu yenerdi.


DÜZENLEME

: Sadece tekrar bu karşılaştım ve bazı gerçek sayılar ile gelip denemek düşündüm. İşte, üç yöntemin tümünü ( matches() ve Pattern ve Character.isLetter()'u önbelleğe almadan) kontrol ederek bir referans noktasında denemem. Ayrıca, bazı şeyleri çarpıtmamak için hem geçerli hem de geçersiz karakterlerin kontrol edildiğinden emin oldum.

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

Ve çıkışı:

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

Yani bu bile önbelleğe alınmış Pattern ile, daha iyi neredeyse 8x bu. (Ve önbelleğe alınmamış, önbelleğe alınmasından yaklaşık 3 kat daha kötüdür.)

+3

'testCharacter()' içinde 'c.charAt (0)' yerine 'c.codePointAt (0)' kullanmalısınız; aksi halde BMP dışındaki karakterler için başarısız olur. –