在前面讲解 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-- 初级篇(五): 操作符重载(1)
实例讲解:
- 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 中字符串的操作就写到这里, 其实还有很多功能, 虽然在开发中用到的地方不是特别多, 但是我们最起码能应该有个了解. 有兴趣的朋友可以去看看其源码的实现.
源代码 https://github.com/Jetictors/KotlinLeran/blob/master/src/com/kotlin/leran/basis/OperatorStringDemo.kt
如果各位大佬看了之后感觉还阔以, 就请各位大佬随便 star 一下, 您的关注是我最大的动力.
来源: https://www.cnblogs.com/Jetictors/p/9232375.html