在前面講解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:Jetictors