簡化你的 java 字符串操做:Guava 之 CharMatcher 用法簡介

對字符串的處理應該是編程活動中最頻繁的操做了,而原生的 JDK 以及 Java 自己的語法特性使得在 Java 中進行字符串操做是一件極其麻煩的事情,若是你熟悉 Shell/Awk/Sed/Perl/Python 等腳本語言,你就大概能明白我說的啥意思了。 html

上次在這篇 使用 Google Guava 美化你的 Java 代碼:1~4  中介紹過一些利用 Guava 庫進行字符串操做的例子,限於篇幅與內容,介紹的比較泛,今天就單獨的聊聊 Guava 中的 CharMatcher 類,並結合一些常見的需求來進行解說。 java

CharMatcher提供了多種對字符串處理的方法, 它的主要意圖有:
1. 找到匹配的字符
2. 處理匹配的字符
git

CharMatcher 的內部實現主要包括兩部分:
1. 實現了大量公用內部類, 用來方便用戶對字符串作匹配: 例如 JAVA_DIGIT 匹配數字, JAVA_LETTER 匹配字母等等。
2. 實現了大量處理字符串的方法, 使用特定的CharMatcher能夠對匹配到的字符串作出多種處理, 例如 remove(), replace(), trim(), retain()等等。
正則表達式

CharMatcher自己是一個抽象類, 其中一些操做方法是抽象方法, 他主要依靠內部繼承CharMatcher的內部子類來實現抽象方法和重寫一些操做方法, 由於不一樣的匹配規則的這些操做方法具備不一樣的實現要求。

apache

一、默認實現類

CharMatcher自己提供了不少CharMatcher實現類,以下: 
ANY: 匹配任何字符
ASCII: 匹配是不是ASCII字符
BREAKING_WHITESPACE: 匹配全部可換行的空白字符(不包括非換行空白字符,例如"\u00a0")
DIGIT: 匹配ASCII數字 
INVISIBLE: 匹配全部看不見的字符
JAVA_DIGIT: 匹配UNICODE數字, 使用 Character.isDigit() 實現
JAVA_ISO_CONTROL: 匹配ISO控制字符, 使用 Charater.isISOControl() 實現
JAVA_LETTER: 匹配字母, 使用 Charater.isLetter() 實現
JAVA_LETTER_OR_DIGET: 匹配數字或字母
JAVA_LOWER_CASE: 匹配小寫
JAVA_UPPER_CASE: 匹配大寫
NONE: 不匹配全部字符
SINGLE_WIDTH: 匹配單字寬字符, 如中文字就是雙字寬
WHITESPACE: 匹配全部空白字符

二、經常使用操做方法

CharMatcher is(char match): 返回匹配指定字符的Matcher
CharMatcher isNot(char match): 返回不匹配指定字符的Matcher
CharMatcher anyOf(CharSequence sequence): 返回匹配sequence中任意字符的Matcher
CharMatcher noneOf(CharSequence sequence): 返回不匹配sequence中任何一個字符的Matcher
CharMatcher inRange(char startInclusive, char endIncludesive): 返回匹配範圍內任意字符的Matcher
CharMatcher forPredicate(Predicate<? super Charater> predicate): 返回使用predicate的apply()判斷匹配的Matcher
CharMatcher negate(): 返回以當前Matcher判斷規則相反的Matcher
CharMatcher and(CharMatcher other): 返回與other匹配條件組合作與來判斷的Matcher
CharMatcher or(CharMatcher other): 返回與other匹配條件組合作或來判斷的Matcher
boolean matchesAnyOf(CharSequence sequence): 只要sequence中有任意字符能匹配Matcher,返回true
boolean matchesAllOf(CharSequence sequence): sequence中全部字符都能匹配Matcher,返回true
boolean matchesNoneOf(CharSequence sequence): sequence中全部字符都不能匹配Matcher,返回true
int indexIn(CharSequence sequence): 返回sequence中匹配到的第一個字符的座標
int indexIn(CharSequence sequence, int start): 返回從start開始,在sequence中匹配到的第一個字符的座標
int lastIndexIn(CharSequence sequence): 返回sequence中最後一次匹配到的字符的座標
int countIn(CharSequence sequence): 返回sequence中匹配到的字符計數
String removeFrom(CharSequence sequence): 刪除sequence中匹配到到的字符並返回
String retainFrom(CharSequence sequence): 保留sequence中匹配到的字符並返回
String replaceFrom(CharSequence sequence, char replacement): 替換sequence中匹配到的字符並返回
String trimFrom(CharSequence sequence): 刪除首尾匹配到的字符並返回
String trimLeadingFrom(CharSequence sequence): 刪除首部匹配到的字符
String trimTrailingFrom(CharSequence sequence): 刪除尾部匹配到的字符
String collapseFrom(CharSequence sequence, char replacement): 將匹配到的組(連續匹配的字符)替換成replacement 
String trimAndCollapseFrom(CharSequence sequence, char replacement): 先trim在replace

三、一些栗子:

(1)使用預約義的常量 (predefine CharMatcher)

CharMatcher.WHITESPACE (Java whitespace character)
CharMatcher.JAVA_DIGIT
CharMatcher.JAVA_LETTER
CharMatcher.JAVA_LOWER_CASE 
CharMatcher.JAVA_UPPER_CASE 
CharMatcher.ASCII
CharMatcher.ANY
...
編程

String str = "FirstName LastName +1 123 456 789 !@#$%^&*()_+|}{:\"?><";
// Use a predefined constant (predefine CharMatcher) 
CharMatcher.DIGIT.retainFrom(str);
 
Output:->
"1123456789"
 
CharMatcher.JAVA_LETTER.retainFrom(str);
 
Output:->
"FirstNameLastName"
 
CharMatcher.JAVA_LETTER_OR_DIGIT.retainFrom(str);
 
Output:->
"FirstNameLastName1123456789"
 
CharMatcher.ANY.countIn(str)
 
Output:->
54
 
CharMatcher.DIGIT.countIn(str);
 
Output:->
10

(2)使用工廠方法:

CharMatcher.is('x')
CharMatcher.isNot('_')
CharMatcher.oneOf("aeiou").negate()
CharMatcher.inRange('a', 'z').or(inRange('A', 'Z'))
...
使用條件組合:
api

CharMatcher and(CharMatcher other) 
CharMatcher or(CharMatcher other) 
CharMatcher negate() 
app

String str = "FirstName LastName +1 123 456 789 !@#$%^&*()_+|}{:\"?><";
 
CharMatcher.JAVA_LOWER_CASE.negate().retainFrom(str);
Output:->
"FN LN +1 123 456 789 !@#$%^&*()_+|}{:\"?><"
 
CharMatcher.JAVA_DIGIT.or(CharMatcher.anyOf("aeiou")).retainFrom(str);
Output:->
"iaeaae1123456789"

(3)一些小例子:

//原字符串
System.out.println(string);

//去掉控制字符(\t,\n,\b...)
System.out.println(CharMatcher.JAVA_ISO_CONTROL.removeFrom(string));

//獲取全部的數字
System.out.println(CharMatcher.DIGIT.retainFrom(string));

//把多個空格替換爲一個包括\t,並去掉首位的空格
System.out.println(CharMatcher.WHITESPACE.trimAndCollapseFrom(string, ' '));

//把全部的數字用"*"代替
System.out.println(CharMatcher.JAVA_DIGIT.replaceFrom(string, "*"));

//獲取全部的數字和小寫字母
System.out.println(CharMatcher.JAVA_DIGIT.or(CharMatcher.JAVA_LOWER_CASE).retainFrom(string));

//獲取全部的大寫字母
System.out.println(CharMatcher.JAVA_UPPER_CASE.retainFrom(string));

//獲取全部單字節長度的符號
System.out.println(CharMatcher.SINGLE_WIDTH.retainFrom(string));
		
/*
原字符串:
  ROCKY  rocky  RoCkY ~!@#$%^&*()      23(*&gS   你好	234啊   GES  

去掉控制字符(\t,\n,\b...):
  ROCKY  rocky  RoCkY ~!@#$%^&*()      23(*&gS   你好234啊   GES  

獲取全部的數字:
23234

把多個空格替換爲一個包括\t,並去掉首位的空格:
ROCKY rocky RoCkY ~!@#$%^&*() 23(*&gS 你好 234啊 GES

把全部的數字用"*"代替:
  ROCKY  rocky  RoCkY ~!@#$%^&*()      **(*&gS   你好	***啊   GES  

獲取全部的數字和小寫字母:
rockyok23g234

獲取全部的大寫字母:
ROCKYRCYSGES

獲取全部單字節長度的符號:
  ROCKY  rocky  RoCkY ~!@#$%^&*()      23(*&gS   	234   GES  
*/

(4)用正則做爲匹配、判斷條件

須要說明的是 CharMatcher 並無提供以正則表達式做爲匹配條件的方法, ui

你能夠參考: google

http://stackoverflow.com/questions/12378702/how-to-write-the-charmatcher-equivalent-for-the-regex-word-character

http://blog.csdn.net/firecoder/article/details/5827281  七種武器:Collection 之 Google Guava

不過這個例子貌似只能判斷字符,而不是字符串。

可是這難不倒咱們,別忘了在上篇文章的最後的連接裏,我提到了另外一個與 guava 相似的庫:Apache Commons,相對而言,它的功能更加完善,好比,這個需求,它內置了一個專門的校驗類:Validate

try {
	Validate.matchesPattern("2013-11-241", "\\d{4}-\\d{2}-\\d{2}", "輸入的日期格式不正確!");
} catch (Exception e) {
	System.out.println(e.toString());
	// return;
}

// output:
// java.lang.IllegalArgumentException: 輸入的日期格式不正確!
因此,我我的傾向於把這兩個庫結合起來用,這樣能夠大大節約你的開發時間,下降你的代碼冗餘度。

好吧,就介紹到這裏了,若是你也有這塊的心得體會,歡迎交流~

四、Refer:

http://www.cnblogs.com/zemliu/p/3345087.html#top

http://techneerajnandwana.blogspot.com/2011/11/guava-string-manipulation-with.html

http://blog.csdn.net/rocky225/article/details/8289407

http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/index.html

http://commons.apache.org/proper/commons-lang/javadocs/api-release/index.html

相關文章
相關標籤/搜索