在前面講解Kotlin
數據類型的時候,提到了字符串類型,當然關於其定義在前面的章節中已經講解過了。對Kotlin
中的數據類型不清楚的同學。請參考Kotlin——初級篇(三):數據類型詳解這篇文章。
在這篇文章中,會對字符串(String
)的常用操作做出一個講解。比如,字符串的截取、查找、獲取長度、替換等等...
目錄
一、字符串查找
字符串查找功能在實際開發中,只會用到幾個簡單的函數,這里我只說明幾個常用的。
1.1、獲取第一個元素
val str = "kotlin very good"
str.first() <=> str[0] <=> str.get(0)
其還實現了查找等於某一個字符的第一個元素,即first{}
高階函數
val str = "kotlin very good"
// 如果未查找到滿足條件的元素,會拋出NoSuchElementException異常
str.first{ it == 'o' }
還有一個firstOrNull()
函數,它和first()
函數的區別在於如果字符串為空串時,first()
函數會拋出異常,而firstOrNull()
函數會返回null
。當然還有firstOrNull{}
函數,它和first{}
函數的區別在於如果字符串為空串時,first{}
函數會拋出異常,而firstOrNull{}
函數會返回null
1.2、 獲取最后一個元素
val str = ...
str.last() <==> str.get(lastIndex) <==> str[lastIndex]
其中 lastIndex 是一個拓展屬性,其實現是 length - 1
同時還實現了查找等於某一個字符的最后一個元素,即last{}
高階函數
val str = "kotlin very good"
// 如果未查找到滿足條件的元素,會拋出NoSuchElementException異常
str.last{ it == 'o' } // 其實從源碼中我們發現其是對原字符串反轉之后再進行遍歷查找滿足條件的元素。
lastOrNull()
同firstOrNUll()
一樣。lastOrNull{}
同firstOrNUll{}
一樣。
1.3、查找元素
其實查找元素提供了兩個高階函數find{}
、findLast{}
。不過他們都是對firstOrNull()
或lastOrNull()
函數進行處理。這里不多作累述。
1.3、 查找對應元素的下標
這里提供查找對應元素下標的幾個函數:
indexOf()
: 查找某一個元素或字符串在原字符串中第一次出現的下標。indexLastOf()
: 查找某一個元素或字符串在原字符串中最后一次出現的下標。indexOfFirst{}
: 同indexOf()
indexOfLast{}
: 同indexLastOf()
例:
println(str.indexOfFirst { it == 'o' })
println(str.indexOfLast { it == 'o' })
println(str.indexOf('o',0))
println(str.indexOf("very",0))
println(str.lastIndexOf('o'))
println(str.lastIndexOf("good"))
輸出結果為:
1
14
1
7
14
12
二、字符串截取
如果你有Java
或者其他語言的編程基礎。相信您對字符串的截取應該不會陌生。您可以繼續的往下看,就當作是對字符串截取只是的一個鞏固。當然,您也可以直接的跳過本節內容,因為在Kotlin
中,字符串的截取的函數subString()
是調用了Java
中的subString()
函數。
在Kotlin
中除了調用subString()
函數外,還可以調用subSequence()
函數,有興趣的朋友可以去看看源碼。
2.1、 用subString()
函數截取
我們看一看subString()
函數的源碼
@kotlin.internal.InlineOnly
public inline fun String.substring(startIndex: Int): String = (this as java.lang.String).substring(startIndex)
@kotlin.internal.InlineOnly
public inline fun String.substring(startIndex: Int, endIndex: Int): String
= (this as java.lang.String).substring(startIndex, endIndex)
public fun String.substring(range: IntRange): String = substring(range.start, range.endInclusive + 1)
從以上的源碼中我們可以看出,Kotlin
中是使用了Java
中的subString()
函數
其中:
startIndex
參數:截取字符串的開始下標endIndex
參數:截取字符串的結束下標rang
參數,是指一個IntRang
類型
實例:
val str = "Kotlin is a very good programming language"
println("s = ${str.substring(10)}") // 當只有開始下標時,結束下標為length - 1
println(str.substring(0,15))
println(str.substring(IntRange(0,15)))
輸出結果為:
a very good programming language
Kotlin is a ver
Kotlin is a very
注意:
- 使用
subString(startIndex,endIndex)
和subString(rang)
時的區別。可以從上邊的結果結合源碼可以看出來。 - 切記下標越界的情況。即
StringIndexOutOfBoundsException
異常
2.2、用subSequence()
函數截取
在Kotlin
中除了使用上面講解到的使用subString()
截取字符串外,還可以使用subSequence()
函數截取。
我們看一看其源碼實現:
public fun subSequence(startIndex: Int, endIndex: Int): CharSequence
public fun CharSequence.subSequence(range: IntRange): CharSequence = subSequence(range.start, range.endInclusive + 1)
從源碼中我們可以看出,其大致和subString()
函數一樣,但是其不提供只傳遞startIndex
的情況
實例:
val str = "Kotlin is a very good programming language"
println(str.subSequence(0,15))
println(str.subSequence(IntRange(0,15)))
輸出結果為:
Kotlin is a ver
Kotlin is a very
三、字符串替換
同上述字符串截取一樣,如果您有編程經驗,可跳過此節。不過對於字符串替換功能,Kotlin
除了實現Java
中的replace()
ha函數外,還提供了另外的replaceFirst()
、replaceAfter()
、replaceBefore()
、replaceIndent()
、等函數。下面會對這些函數意義進行實例講解。
3.1、replace()函數
replace()
函數提供了4個重載函數。他們能實現不同的功能
3.1.1、 replace(oldChar,newChar,ignoreCase = false)
其中:
- 作用 : 把原字符串中的某一個字符全部替換成新的字符。然后返回新的字符串
- 參數說明:
oldChar
: 需要替換的字符newChar
: 新的字符ignoreCase
: 是否引用Java
中的replace()
函數。默認值為false
,即用Java
的replace()
函數
例:
// 把字符`a`全部替換為`A`
val str = "Kotlin is a very good programming language"
println(str.replace('a','A'))
輸出結果為:
Kotlin is A very good progrAmming lAnguAge
3.1.2、 replace(oldValue,newValue,ignoreCase = false)
其中:
- 作用 : 把原字符串中的某一個字符全部替換成新的字符。然后返回新的字符串
- 參數說明:
oldValue
: 需要替換的字符串newValue
: 新的字符串ignoreCase
: 是否引用Java
中的replace()
函數。默認值為false
,即用Java
的replace()
函數
例:
// 把字符串`Kotlin`替換成字符串`Java`
val str = "Kotlin is a very good programming language"
println(str.replace("Kotlin","Java"))
輸出結果為:
Java is a very good programming language
3.1.3、 replace(regex,replacement)
其中:
- 作用 : 根據定義的正則規則去匹配源字符串,把滿足規則的字符串替換成新的字符串。
- 參數說明:
regex
: 正則表達式replacement
: 新的字符串
例:
// 正則的規則為檢測數字,如果為數字則替換成字符串`kotlin`
val str = "1234a kotlin 5678 3 is 4"
println(str.replace(Regex("[0-9]+"),"kotlin"))
輸出結果為:
kotlina kotlin kotlin kotlin is kotlin
3.1.4、replace(regex: Regex, noinline transform: (MatchResult) -> CharSequence)
其中:
- 作用 : 根據定義的正則規則去匹配源字符串,把滿足規則的字符串通過
transform{}
高階函數映射的新字符串替換。- 參數說明:
regex
: 正則表達式transform
: 高階函數
例:
val str = "1234a kotlin 5678 3 is 4"
val newStr = str.replace(Regex("[0-9]+"),{
"abcd "
})
輸出結果為:
abcd abcd abcd abcd a kotlin abcd abcd abcd abcd abcd is abcd
可以從上述的兩個函數中看到兩個函數的區別。關於高階函數
、正則表達式
的知識點可以先自行看資料理解。小生會在后續的章節中補上相關的內容...
經過上面的replace()
函數的講解。並且對幾個重載函數進行了分析。相信大家對replace()
函數中的參數都有大致的了解。並且下面的幾個函數也是大致相同的操作。故而下面的幾個函數操作,我只會舉例說明其作用。關於參數的介紹就不作細究了
3.2、replaceFirst()函數
作用:把滿足條件的第一個字符或字符串替換成新的字符或字符串
例:
val str = "Kotlin is a very good programming language"
println(str.replaceFirst('a','A'))
println(str.replaceFirst( "Kotlin","Java"))
輸出結果為:
Kotlin is A very good programming language
Java is a very good programming language
3.3、replaceBefore()函數
作用:截取滿足條件的第一個字符或字符串后面的字符串,包含滿足條件字符或字符串自身,並在其前面加上新的字符串。
例:
val str = "Kotlin is a very good programming language"
println(str.replaceBefore('a',"AA"))
println(str.replaceBefore("Kotlin","Java"))
輸出結果為:
AAa very good programming language
JavaKotlin is a very good programming language
3.4、replaceBeforeLast()函數
作用:截取滿足條件的最后一個字符或字符串后面的字符串,包含滿足條件字符或字符串自身,並在其前面加上新的字符串。
例:
val str = "Kotlin is a very good programming language"
println(str.replaceBeforeLast('a',"AA"))
println(str.replaceBeforeLast("Kotlin","Java"))
輸出結果為:
AAage
JavaKotlin is a very good programming language
3.5、replaceAfter()函數
作用:截取滿足條件的第一個字符或字符串前面的字符串,包含滿足條件字符或字符串自身,並在其后面加上新的字符串。
例:
val str = "Kotlin is a very good programming language"
println(str.replaceAfter('a',"AA"))
println(str.replaceAfter("Kotlin","Java"))
輸出結果為:
Kotlin is aAA
KotlinJava
3.6、replaceAfterLast()函數
作用:截取滿足條件的最后一個字符或字符串前面的字符串,包含滿足條件字符或字符串自身,並在其后面加上新的字符串。
例:
val str = "Kotlin is a very good programming language"
println(str.replaceAfterLast('a',"AA"))
println(str.replaceAfterLast("Kotlin","Java"))
輸出結果為:
Kotlin is a very good programming languaAA
KotlinJava
四、字符串分割
同上一節一樣,Kotlin
除了實現Java
中的split()
函數之外,還提供了splitToSequence()
函數來分割字符串。分割成功后都會返回一個字符串集合用於我們后續操作。
4.1、 split()函數
split()
函數也是提供了4
個重載函數。其中,用正則表達式為條件分割占用兩個。用字符分割占用一個。用字符串分割占用一個。
4.1.2、使用正則表達式分割
在Kotlin
中使用正則表達式,使用的是Regex
類,而Java
中使用正則表達式使用的Pattern
類。這里分別舉例說明
例:
var str2 = "1 kotlin 2 java 3 Lua 4 JavaScript"
val list3 = str2.split(Regex("[0-9]+"))
for (str in list3){
print("$str \t")
}
println()
val list4 = str2.split(Pattern.compile("[0-9]+"))
for (str in list4){
print("$str \t")
}
輸出結果為:
kotlin java Lua JavaScript
kotlin java Lua JavaScript
4.1.2、使用字符或字符串分割
在實際的項目開發中,還是這種方式用的要多一些。不過這里值得注意的是,不管是用字符分割,還是字符串分割,其都是一個可變參數。即其參數的個數不定。
例:
val str1 = "Kotlin is a very good programming language"
val list1 = str1.split(' ')
for (str in list1){
print("$str \t")
}
println()
val list2 = str1.split(" ")
for (str in list2){
print("$str \t")
}
輸出結果為:
Kotlin is a very good programming language
Kotlin is a very good programming language
這里舉例一個可變參數情況的例子:
val str3 = "a b c d e f g h 2+3+4+5"
val list5 = str3.split(' ','+')
for (str in list5){
print("$str \t")
}
輸出結果為:
a b c d e f g h 2 3 4 5
4.2、 splitToSequence()函數
此函數同樣可以用字符串或字符去分割,其用法和上述的split()
函數一樣。這里就不多累述了...
五、其他
除了上面講解到的幾點外,還有很多常用的處理,比如檢測字符串是否為空串,是否為null
,獲取字符串長度,字符串反轉,統計,轉換字符數組,獲取指定下標的字符等等。
5.1、 獲取字符串長度
在
Kotlin
中用兩種獲取字符串長度的方法。其實也是一種而已
- 直接用
length
屬性獲取長度- 用
count()
函數獲取,其實count()
函數的做法也是返回了length
長度。
實例:
val str = "kotlin very good"
// 1. 直接用length屬性獲取
println("str.length => ${str.length}")
// 2. 用count()函數獲取
println("str.count() => ${str.count()}")
輸出結果為:
str.length => 16
str.count() => 16
這里我們看一看count()
函數的源碼
/**
* Returns the length of this char sequence.
* 其實也就是返回了length屬性...
*/
@kotlin.internal.InlineOnly
public inline fun CharSequence.count(): Int {
return length
}
5.2、統計重復字符
上面講到了count()
函數,是返回了length
屬性獲取字符串的長度。其實源碼中還提供了一個叫count{}
的高階函數,用於統計字符串中重復某個字符的個數。
看一看他的源碼
public inline fun CharSequence.count(predicate: (Char) -> Boolean): Int {
var count = 0
for (element in this) if (predicate(element)) count++
return count
}
源碼解釋:該函數接受一個Boolean
類型的Lambda
表達式。然后循環這個字符串,如果我的條件成立,則變量count
自增。循環完成之后返回重復的個數count
實例:
val str = "kotlin very good"
val count = str.count { it == 'o' }
println("count : $count")
輸出結果為:
count : 3
5.3、 驗證字符串
在實際的開發中,特別是Android
開發中,會經常遇到驗證輸入框的內容是否為空串的時候。在Kotlin
中,和Java
一樣提供了幾個處理這種情況的函數。
下列幾個函數都是處理字符串為空串或為空的:
isEmpty()
: 其源碼是判斷其length
是等於0
,若等於0
則返回true
,反之返回false
。不能直接用於可空的字符串isNotEmpty()
: 其源碼是判斷其length
是否大於0
,若大於0
則返回true
,反之返回false
。不能直接用於可空的字符串isNullOrEmpty()
: 其源碼是判斷該字符串是否為null
或者其length
是否等於0
。isBlank()
: 其源碼是判斷其length
是否等於0
,或者判斷其包含的空格數是否等於當前的length
。不能直接用於可空的字符串isNotBlank()
: 其源碼是對isBlank()
函數取反。不能直接用於可空的字符串isNotOrBlank()
: 其源碼判斷該字符串是否為null
。或者調用isBlank()
函數
實例:
val str : String? = "kotlin"
// 可以看出當str為可空變量的時候,isNullOrEmpty()和isNotOrBlank()可以不做直接調用而不做任何處理
,而其他的函數則不行
println(str?.isEmpty())
println(str?.isNotEmpty())
println(str.isNullOrEmpty())
println(str?.isBlank())
println(str?.isNotBlank())
println(str.isNullOrBlank())
輸出結果為:
false
true
false
false
true
false
5.4、字符串連接
字符串鏈接,在Java
中只能使用+
來鏈接,當然除了StringBuilder、StringBuffer
除外。而在Kotlin
中除了使用+
以外,還可以使用plus()
函數。其接受任意類型。plus()
函數是一個運算符重載函數。在前面的章節中講解過了。若你對Kotlin
中的雲素福重載不了解,您可以查看我的另一篇文章:Kotlin——初級篇(五):操作符與操作符重載一
實例講解:
val oldStr = "kotlin"
println(oldStr.plus(" very good"))
println(oldStr + " very good")
輸出結果為:
kotlin very good
kotlin very good
5.5、字符串反轉
和數組一樣,字符串也是可以反轉元素的。直接使用reversed()
函數即可。
例:
val str = "kotlin"
println("字符串反轉:${str.reversed()}")
輸出結果:
字符串反轉:niltok
5.6、判斷字符串的起始與結尾
在實際的開發中,判斷字符串的起始與結尾是很常用的。
5.6.1、 startsWith()
其中:
作用: 判斷其字符串是否由某一個字符或字符串起始。
參數說明:
char
: 起始字符prefix
: 起始字符串ignoreCase
: 是否調用Java
中的此函數。默認為false
startIndex
: 開始位置
例:
val str = "kotlin"
str.startsWith('k') // 是否有字符`k`起始
str.startsWith("Kot") // 是否由字符串`kot`起始
str.startsWith("lin",3) // 當起始位置為3時,是否由字符串`lin`起始
輸出結果為:
true
true
true
5.6.2、endsWith()
其中:
作用: 判斷其字符串是否由某一個字符或字符串結尾。
參數說明:
char
: 結尾字符suffix
: 結尾字符串ignoreCase
: 是否調用Java
中的此函數。默認為false
例:
val str = "kotlin"
println(str.endsWith("lin")) // 是否由字符串`lin`結尾
println(str.endsWith('n')) // 是否由字符`n`結尾
輸出結果為:
true
true
總結
在實際的項目開發中,字符串的處理使用的情況是很多的。特別是字符串的驗證處理、替換、分割、截取。這也是我把這些知識點整理出來的原因。這些知識點是很基礎,但同時也是很常用的。如果您有編程經驗的話您就當對字符串的基礎知識的鞏固。
關於kotlin
中字符串的操作就寫到這里,其實還有很多功能,雖然在開發中用到的地方不是特別多,但是我們最起碼能應該有個了解。有興趣的朋友可以去看看其源碼的實現。
如果各位大佬看了之后感覺還闊以,就請各位大佬隨便star
一下,您的關注是我最大的動力。
我的個人博客:Jetictors
Github:Jteictors
掘金:Jteictors