本文是對 Guava 中 CharMatcher 的學(xué)習(xí)介紹。歡迎加入學(xué)習(xí)項(xiàng)目: LearningGuava沟突。
以下參考:
概覽
之前炼邀,Guava 中的 StringUtil
在無節(jié)制地增長陆错,具有很多方法灯抛,如:
allAscii
collapse
collapseControlChars
collapseWhitespace
lastIndexNotOf
numSharedChars
removeChars
removeCrLf
retainAllChars
strip
stripAndCollapse
stripNonDigits
這些函數(shù)本質(zhì)上是以下兩個(gè)方面的乘積(M x N 種情況):
- 何如定義一個(gè)“匹配”的字符? (M 種情況)
- 對“匹配”的字符進(jìn)行怎樣的操作音瓷? (N 種情況)
為了解決這樣的爆炸式增長对嚼,Guava 提供了 CharMatcher
。一個(gè) CharMacher
實(shí)例本身绳慎,界定了一個(gè)匹配字符的集合纵竖,而 CharMacher 實(shí)例的方法,解決了要對匹配字符做什么的問題杏愤。然后我們就可以用最小化的 API 來處理字符匹配和字符操作靡砌,把 M×N 的復(fù)雜度下降到了 M+N。
直觀地說珊楼,你可以把 CharMatcher
看做是一些特別字符串的表示通殃,例如:數(shù)字、空格等厕宗。而事實(shí)上画舌,CharMatcher
只是一個(gè)針對字符串的布爾斷言(它實(shí)現(xiàn)了 Predicate<Character>
),但考慮到“所有空白字符串”已慢、“所有小寫單詞”等相關(guān)需求是很普遍的曲聂,Guava 還是為字符串提供了專門的語法和 API。
CharMatcher
的功能主要在于對特定類或字符串執(zhí)行這些操作:trimming
佑惠、collapsing
句葵、removing
厕鹃、retaining
等。
使用示例
創(chuàng)建 CharMatcher
很多需求都可以被 CharMatcher
的工廠方法滿足:
any()
none()
whitespace()
breakingWhitespace()
invisible()
digit()
javaLetter()
javaDigit()
javaLetterOrDigit()
javaIsoControl()
javaLowerCase()
javaUpperCase()
ascii()
singleWidth()
其它一些常用的獲得一個(gè) CharMatcher
的方法包括:
方法 | 描述 |
---|---|
anyOf(CharSequence) |
表明你想匹配的所有字符乍丈,例如:CharMatcher.anyOf("aeiou") 可以匹配小寫元音字母剂碴。 |
is(char) |
表明你想匹配的一個(gè)確定的字符。 |
inRange(char, char) |
表明你想匹配的一個(gè)字符范圍轻专,例如:CharMatcher.inRange('a', 'z') 忆矛。 |
此外,CharMatcher
還有這些方法:negate()
请垛、and(CharMatcher)
催训、or(CharMatcher)
。這些方法可以為 CharMatcher
提供方便的布爾運(yùn)算宗收。
使用 CharMatcher
CharMatcher
提供了很多方法來對匹配的字符序列 CharSequence
進(jìn)行操作漫拭。以下只是列出了一些常用方法。
方法 | 描述 |
---|---|
collapseFrom(CharSequence, char) |
將一組連續(xù)匹配的字符串替換為一個(gè)指定的字符混稽。例如:WHITESPACE.collapseFrom(string, ' ') 可以將連續(xù)的空字符串替換為單個(gè)字符采驻。 |
matchesAllOf(CharSequence) |
測試字符序列是否全部匹配。例如:ASCII.matchesAllOf(string) 可以測試字符是否全部是 ASCII匈勋。 |
removeFrom(CharSequence) |
將匹配的字符序列移除 |
retainFrom(CharSequence) |
將沒有匹配的字符序列移除 |
trimFrom(CharSequence) |
去除開頭和結(jié)尾匹配的部分 |
replaceFrom(CharSequence, CharSequence) |
將匹配的字符替換為給定的序列 |
方法分類
根據(jù)函數(shù)的返回值和名稱將這些方法分為三類礼旅。
第一類是判定型函數(shù),判斷 CharMacher
和入?yún)⒆址钠ヅ潢P(guān)系洽洁。
CharMatcher.is('a').matchesAllOf("aaa");//true
CharMatcher.is('a').matchesAnyOf("aba");//true
CharMatcher.is('a').matchesNoneOf("aba");//true
第二類是計(jì)數(shù)型函數(shù)痘系,查找入?yún)⒆址械谝淮巍⒆詈笠淮纬霈F(xiàn)目標(biāo)字符的位置饿自,或者目標(biāo)字符出現(xiàn)的次數(shù)汰翠,比如 indexIn
,lastIndexIn
和 countIn
昭雌。
CharMatcher.is('a').countIn("aaa"); // 3
CharMatcher.is('a').indexIn("java"); // 1
第三類就是對匹配字符的操作复唤。包括 removeFrom
、retainFrom
城豁、replaceFrom
苟穆、trimFrom
、collapseFrom
等唱星。
CharMatcher.is('a').retainFrom("bazaar"); // "aaa"
CharMatcher.is('a').removeFrom("bazaar"); // "bzr"
CharMatcher.anyOf("ab").trimFrom("abacatbab"); // "cat"
源碼分析
源碼有很多行雳旅,主要的邏輯是這樣的:
-
CharMatcher
是個(gè)抽象類,內(nèi)部有一些私有的實(shí)現(xiàn)類间聊,通過一些工廠函數(shù)is
攒盈、anyOf
等工廠函數(shù)創(chuàng)建對應(yīng)的實(shí)例(固定的是單例,變化的會(huì)創(chuàng)建一個(gè)具體實(shí)例)哎榴。 - 不同的實(shí)例主要實(shí)現(xiàn)的是
CharMatcher
中的matches
方法型豁,這樣就實(shí)現(xiàn)了不同策略的匹配器僵蛛。 - 基于上述匹配方法
matches
,可以進(jìn)行統(tǒng)計(jì)工作(countIn
等)迎变、查找工作(indexIn
等)充尉、修改工作(trimFrom
)等。
這樣的設(shè)計(jì)最基礎(chǔ)的工作就是:把匹配部分進(jìn)行抽象衣形。此外驼侠,在具體實(shí)現(xiàn)過程中也有較多的優(yōu)化,就不一一列出來了谆吴。