摘要:比如的結(jié)果是,長(zhǎng)度為,因?yàn)槭紫绕ヅ淙我庾址?,所以原字符串中每一個(gè)都是分割符,這就產(chǎn)生了個(gè)空字符串,然后默認(rèn)為,從后往前刪除空字符串,結(jié)果就為空。
在 Java 中處理字符串時(shí),split 是一個(gè)很常用的操作,但是這一簡(jiǎn)單的操作,卻經(jīng)常有意想不到的結(jié)果,就拿Guava庫(kù)官方教程中的一個(gè)例子來說,",a,,b,".split(",") 的結(jié)果是?
1. "", "a", "", "b", "" 2. null, "a", null, "b", null 3. "a", null, "b" 4. "a", "b" 5. None of the above
正確答案應(yīng)該是 5,以上都不對(duì);正確結(jié)果是 ["", "a", "", "b"]。
正是因?yàn)?JDK 自帶的 split 這種奇怪的現(xiàn)象,其他開源庫(kù)也都給出了自己的 split 方法,如 Apache Commons Lang 和上文中的 Guava 。
split in JDK8String 類包含兩個(gè) split 重載方法,public String[] split(String regex) 和 public String[] split(String regex, int limit),調(diào)用前者就相當(dāng)于默認(rèn) limit = 0,而上面的例子中奇怪的現(xiàn)象就和這個(gè) limit 有關(guān)。
JDK 文檔中是這么解釋的:
當(dāng) limit 即 n 大于 0 時(shí),會(huì)返回至多 n 項(xiàng),最后一項(xiàng)會(huì)包含所有未被拆分的部分
當(dāng) n 小于 0 時(shí),會(huì)返回所有拆分后的結(jié)果
當(dāng) n 等于 0 時(shí),會(huì)返回所有拆分后的結(jié)果,但是最后跟著的空字符串會(huì)被刪除
由于使用了單參數(shù)的 split 方法,n == 0,于是就產(chǎn)生了如上的結(jié)果。關(guān)于這一部分的 JDK 中的源碼部分如下:
// Construct result int resultSize = list.size(); if (limit == 0) { while (resultSize > 0 && list.get(resultSize - 1).length() == 0) { resultSize--; } }
平常在分析一些具有固定格式的數(shù)據(jù)時(shí),比如每一行都是 tab 分割的,且有固定列數(shù),那么進(jìn)行解析時(shí)可以使用 s.split(" ", -1) 來進(jìn)行操作。這樣會(huì)保存所有的分割項(xiàng),包含任意部位的空字符串,比如
":a::b::".split(":", -1) => ["", "a", "", "b", "", ""]
另外一個(gè)需要注意的地方是,split 接收的參數(shù)是一個(gè)正則表達(dá)式,這一點(diǎn)經(jīng)常容易忽略。比如 "a.b.c".split(".") 的結(jié)果是 [],長(zhǎng)度為 0 ,因?yàn)槭紫?. 匹配任意字符,所以原字符串中每一個(gè)都是分割符,這就產(chǎn)生了 6 個(gè)空字符串, 然后 limit 默認(rèn)為 0 ,從后往前刪除空字符串,結(jié)果就為空。
split in Commons LangJDK 中的方法畢竟還是簡(jiǎn)單了一些,不能滿足我們一些特殊需求,或者說不想使用正則,那么可以使用 Commons Lang 庫(kù)中的方法。這些 split 方法有以下特點(diǎn):
如果沒有指定結(jié)果個(gè)數(shù),都默認(rèn)輸出最多項(xiàng)
如果沒有 PreserveAllTokens 后綴,默認(rèn)將多個(gè)連續(xù)分割符視為 1 個(gè),不保留任意位置空字符串
比如:
StringUtils.split("::a::b::", ":") => ["a", "b"]
需要注意的是 split(String str, String separatorChars) 方法中第二個(gè)參數(shù)的意義是每一個(gè)字符都被當(dāng)成分割符,比如:
StringUtils.split(":a:b:", "ab") => [":", ":", ":"]
那么假如我想用 "ab" 整體作為分割符呢,可以使用 splitByWholeSeparator 方法:
StringUtils.splitByWholeSeparator("abcabc","ab") => ["c", "c"]
但這個(gè)方法有一個(gè)和其他方法表現(xiàn)不一致的地方,它保留了末尾的空字符串,且只保留一個(gè)。
StringUtils.splitByWholeSeparator("abb", "bb") => ["a", ""] StringUtils.splitByWholeSeparator("bba", "bb") => ["a"] StringUtils.splitByWholeSeparator("abbbbabbbb", "bb") =>["a", "a", ""]
另外一個(gè)我覺得很有用的就是一系列 splitPreserveAllTokens 重載函數(shù)了,因?yàn)槟J(rèn)輸出所有結(jié)果,且保留了空字符串。和 JDK 中的 limit = -1 結(jié)果一致,但更易讀一些。
split in Guava假如你已經(jīng)被上面這些特殊情況都繞暈了,不妨試試 Guava 庫(kù),它沒有提供簡(jiǎn)單的一系列重載 split 方法,而是提供了一系列的工廠方法,采用鏈?zhǔn)秸{(diào)用,從而從方法名上就能看出結(jié)果,不用苦思冥想到底有沒有陷阱。
Splitter.on(",") .trimResults(CharMatcher.is(",")) .omitEmptyStrings() .limit(2) .split("a,,,,,b,,,,c,,,") => ["a", "b,,,,c"]
除了按照分割符外,還可以按照長(zhǎng)度:
Splitter.fixedLength(3).split("abcde") => ["abc", "de"]
不像 JDK 和 Commons Lang 中的返回?cái)?shù)組,Guava 返回 Iterable 和 List,而且這個(gè) Iterable 已經(jīng)重載了 toString,可以方便地進(jìn)行打印測(cè)試。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/68045.html
摘要:元組也支持內(nèi)置函數(shù)的參數(shù)必須是一個(gè)序列字符串列表元組元組有什么用既然中有這么個(gè)數(shù)據(jù)結(jié)構(gòu),自然就有它的用武之地。 引言 想學(xué)爬蟲還是 python 專業(yè)啊,之前一直在用 java, 現(xiàn)在決定嘗嘗鮮,使用 python及爬蟲框架來完成網(wǎng)絡(luò)數(shù)據(jù)采集。編程語(yǔ)言之間都是相通的,比如都需要模塊化,引入其他文件來實(shí)現(xiàn)功能,使用列表等容器來處理數(shù)據(jù),都要使用 json 或 xml 來解析和傳輸數(shù)據(jù)。你...
摘要:元組也支持內(nèi)置函數(shù)的參數(shù)必須是一個(gè)序列字符串列表元組元組有什么用既然中有這么個(gè)數(shù)據(jù)結(jié)構(gòu),自然就有它的用武之地。 引言 想學(xué)爬蟲還是 python 專業(yè)啊,之前一直在用 java, 現(xiàn)在決定嘗嘗鮮,使用 python及爬蟲框架來完成網(wǎng)絡(luò)數(shù)據(jù)采集。編程語(yǔ)言之間都是相通的,比如都需要模塊化,引入其他文件來實(shí)現(xiàn)功能,使用列表等容器來處理數(shù)據(jù),都要使用 json 或 xml 來解析和傳輸數(shù)據(jù)。你...
摘要:字符串在中,萬(wàn)物皆對(duì)象,顯然字符串是對(duì)象類型,用表示。其二是聲明為原始字符串如,由開頭引起的字符串就是聲明了后面引號(hào)里的東西是原始字符串,在里面放任何字符都表示該字符的原始含義,不需要再用轉(zhuǎn)義符了。 Python字符串 在Python中,萬(wàn)物皆對(duì)象,顯然字符串是對(duì)象類型,用str表示。字符串類型通常用單引號(hào)或者雙引號(hào)包裹起來。 >>> Hello,world Hello,world >...
摘要:大家好我是小小明,今天給大家演示如何使用直接采集百度指數(shù)的數(shù)據(jù)。本文不演示如何使用自動(dòng)化工具采集百度指數(shù),為了采集更簡(jiǎn)單將直接讀取并解析接口。 大家好我是小小明,今...
摘要:本題要求編寫程序,計(jì)算個(gè)有理數(shù)的和差積商。輸出格式分別在行中按照有理數(shù)運(yùn)算符有理數(shù)結(jié)果的格式順序輸出個(gè)有理數(shù)的和差積商。注意輸出的每個(gè)有理數(shù)必須是該有理數(shù)的最簡(jiǎn)形式,其中是整數(shù)部分,是最簡(jiǎn)分?jǐn)?shù)部分若為負(fù)數(shù),則須加括號(hào)若除法分母為,則輸出。 本題要求編寫程序,計(jì)算 2 個(gè)有理數(shù)的和、差、積、商。 輸入格式:輸入在一行中按照 a1/b1 a2/b2 的格式給出兩個(gè)分?jǐn)?shù)形式的有理數(shù),其中分...
閱讀 2574·2021-11-18 10:02
閱讀 1713·2021-09-30 10:00
閱讀 5310·2021-09-22 15:27
閱讀 1204·2019-08-30 15:54
閱讀 3671·2019-08-29 11:13
閱讀 2945·2019-08-29 11:05
閱讀 3319·2019-08-29 11:01
閱讀 569·2019-08-26 13:52