2012-04-06 30 views
2

在任何標準庫中,是否有字符類(字母,數字,字母數字)的定義?我檢查,如果字符串只包含字母數字字符或冒號:Java - 靜態定義的字符列表

StringUtils.containsOnly(input, ALPHA_NUMERIC + ":"); 

我可以定義自己ALPHA_NUMERIC,但似乎常用的字符類會在標準庫中進行定義,但我一直無法找到定義。

編輯:我確實考慮過正則表達式,但對於我的特殊用例而言,執行時間非常重要,而且簡單的掃描效率更高。

編輯:下面是測試結果,使用正則表達式,CharMatcher,和一個簡單的掃描(使用相同的一組用於每個測試的有效/無效的輸入字符串的):

有效輸入字符串:

CharMatcher,民運行:1000000,有效的字符串:真,時間(ms):

正則表達式,民運行:1000000,有效的字符串:真,時間(ms):

掃描,民運行:1000000,有效的字符串:真,時間(ms):

無效的輸入字符串:

CharMatcher,民運行:1000000,有效字符串:假的,時間(ms):

的Regex,貨號運行:1000000,弗吉尼亞州蓋字符串:假的,時間(ms):

掃描,貨號運行:1000000,有效字符串:假的,時間(ms):

這裏是所執行的代碼掃描:

public boolean matches(String input) { 
    for(int i=0; i<input.length(); i++) { 
     char c = input.charAt(i); 
     if(!Character.isLetterOrDigit(c) && c != ':') { 
      return false; 
     } 
    } 
    return true; 
} 

編輯:我重新編譯爲一個獨立的程序(我是通過蝕運行):

CharMatcherTester中,Nu米運行:1000000,有效字符串:真,時間(ms):418

RegexTester,貨號運行:1000000,有效字符串:真,時間(ms):812

ScanTester,貨號運行:1000000,有效字符串:真,時間(ms):88

CharMatcherTester,民運行:1000000,有效的字符串:假的,時間(ms):142

RegexTester,民運行:1000000,有效的字符串:假的,時間( ms):223

ScanTester,Num運行:1000000,有效字符串:false,Time( MS):32

來源:https://bitbucket.org/jdeveloperw/testing(這是我第一次發佈的測試結果如此,這樣的評論是值得讚賞)

+0

據我所知沒有這樣的圖書館存在。 – 2012-04-06 00:40:46

+0

這是你正在尋找的:[Character.getType(int)](http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Character.html#getType%28int% 29)和[Character.getType(char)](http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Character.html#getType%28char%29)。 – 2012-04-06 03:19:25

+1

你認爲「äöüÄÜÖßø¢...」是否爲英文字母? – 2012-04-06 03:24:04

回答

5

你最好的選擇可能是一個正則表達式Pattern

應該匹配:

[\p{Alnum}:]* 
  • \p{Alnum} - ASCII字母數字
  • [] - 字符類(任意字符內將匹配一個字符)
  • : - 文字:
  • * - 0或更多

如果它全部是字母數字(或:)。您可以使用matches或預編譯正則表達式。

+0

我確實想過使用正則表達式,但對於我的特殊用例,執行時間非常重要,而且簡單的掃描效率更高。 – 2012-04-06 00:49:53

+1

@JDWhite,你應該基準。 – 2012-04-06 01:02:56

+0

標杆管理是一個好主意,我會比較CharMatcher,正則表達式和掃描,並在有空閒時間後發佈結果。 – 2012-04-06 23:46:21

2

那麼它確實存在,當你在談論regex在這種情況下,字符類\w就是這樣。這就是爲什麼String類具有matches方法。

編輯:當添加了匹配方法時,該StringUtils類可能早於Java 1.4。 Apache Commons類提供的許多功能已被摺疊到標準庫中。當你必須使用老版本的Java,或者你正在使用不在標準庫中的東西時,它們仍然是有用的,但這似乎並不是這種情況之一。

+0

不包括下劃線,但不包括冒號。 – 2012-04-06 00:43:33

+0

嗯,是的,你必須添加冒號到你的模式,就像OP目前正在做的一樣。但是你對下劃線是正確的,我已經忘記了這一點。 – Hiro2k 2012-04-06 00:48:31

2

試試這個,使用正則表達式:

boolean containsOnlyAlphanumeric = input.matches("[\\p{Alnum}:]+"); 

編輯:

對於您可以在最佳性能預編譯的模式,將其存儲在一個靜態定義的模式不變,並再次使用它時,必要:

// part of the class declaration 
private static final Pattern ALPHANUMERIC_PLUS_COLON = Pattern.compile("[\\p{Alnum}:]+"); 

// whenever you need to check if the input matches the pattern 
boolean containsOnlyAlphanumeric = ALPHANUMERIC_PLUS_COLON.matcher(input).matches(); 

我同意Matthew Flaschen,你不應該拋棄正則表達式吧如果不是比檢查輸入字符串中所有可能的有效字符的掃描速度快,那麼構建良好的預編譯正則表達式的速度可能會更快。首先是基準!

+0

^和$是Java中行的開始和結束,而不是輸入。 – 2012-04-06 00:45:53

+0

@MatthewFlaschen它是固定的。你是對的,當使用'matches()'時,不需要'^'和'$'' – 2012-04-06 00:48:43

+0

謝謝,不知道默認情況下它是否匹配整個字符串。 – 2012-04-06 00:55:26

0

正則表達式匹配可以完成這項工作。例如MyString.matches(「[a-zA-Z0-9:] *」);

1

Guava'sCharMatcher幾乎是正好你在問什麼。這裏是wiki article。 (披露:我貢獻番石榴。)

CharMatcher matcher = CharMatcher.JAVA_LETTER_OR_DIGIT.or(
    CharMatcher.is(':')); 
return matcher.matchesAllOf(string);