Kotlin 标准库 Safari:字符串
这篇博文是配合我们YouTube 系列节目“Kotlin 标准库探索之旅”第一集而写的,您可以在我们的官方 Kotlin YouTube 频道上找到该节目,或者直接在这里观看!
什么是 Kotlin 标准库 Safari?
在“Kotlin 标准库探索之旅”系列中,我们将逐一介绍Kotlin 标准库提供的实用功能。在这个过程中,我们希望能够一起发掘一些隐藏的宝藏,它们将在你下次编写 Kotlin 代码时派上用场。因为如果你知道如何正确使用,Kotlin 标准库将是一个强大的工具,可以帮助你更高效地解决问题,并使你的代码更具表现力。
本期节目将全面讲解字符串——我们如何操作字符串、提取信息、比较字符串等等。让我们开始吧!
创建字符串
字符串是最常见的数据类型之一,你可能非常熟悉。毕竟,各种各样的信息都会以某种方式以文本字符串的形式存储。或许在你编写的第一个 Kotlin 程序中,你就已经用到了一个字符串字面量,比如“Hello, World”或类似的内容:
println("Hello, World!") // Hello, World!
但是,您可能知道,即使是字符串字面量在 Kotlin 中也能做更多的事情,而不仅仅是静态存储一些文本。
通过字符串插值(也称为“字符串模板”),我们可以通过引用变量、调用函数甚至计算复杂表达式来丰富我们的字符串:
val name = "Johnathan"
println("Hello, $name!") // Hello, Johnathan
println("Your name is ${name.count()} long!") // Your name is 9 long!
当我们的字符串包含多行文本或通常保留的特殊字符(例如引号或反斜杠)时,我们可以使用多行字符串,多行字符串用三引号表示。一切仍将按预期运行:
val name = """
Johnathan,
The Great,
The "Knowledgeable"
""".trimIndent()
println("Hello, $name!")
println("Your name is ${name.count()} long!")
/* Prints:
Hello, Johnathan,
The Great,
The "Knowledgeable"!
Your name is 41 long!
*/
在IntelliJ IDEA中输入这些用三引号括起来的“原始”字符串时,你会注意到字符串trimIndent()会自动添加一个 `remove` 函数。该函数会移除所有输入行的公共缩进,如果首尾行是空的,也会将其移除。这意味着,例如,如果我们将一些 XML 或 JSON 数据存储在一个字符串中,我们可以保持其良好的格式,而无需担心会引入额外的字符。请注意,在本例中,打印的输出没有缩进,也没有以不必要的空行开头或结尾:
fun main() {
val myJson = """
{
"name": "jane",
"lastname": "doe",
"age": 29
}
""".trimIndent()
println(myJson)
}
/* Prints:
{
"name": "jane",
"lastname": "doe",
"age": 29
}
*/
如果您担心在创建字符串时调用额外函数会影响性能,请不必担心。对于常量字符串,自 Kotlin 1.3.40 起,此转换在编译时进行,不会产生运行时开销。
当然,字符串还可以来自很多其他地方。例如,Kotlin 可以通过函数读取终端输入readLine()。或者,我们可以从文件中读取文本,这只是两个例子:
val fromStdIn = readLine()
val fromFile = File("input.txt").readText()
另一种创建 Kotlin 字符串的巧妙方法是使用 `StringBuilder`buildString函数。我们可以给这个函数提供一个代码块,该代码块会填充一个 ` StringBuilder`对象,从而提供诸如 `String()` 和 `String()` 之类的函数append。如果您要创建大型字符串并且性能是您关注的重点,appendLine那么这种方法尤其有用。
val name = "Jane"
val myString = buildString {
repeat(10) {
append("Hello, ")
append(name)
appendLine("!")
}
}
println(myString)
/* Prints:
Hello, Jane!
Hello, Jane!
Hello, Jane!
Hello, Jane!
Hello, Jane!
Hello, Jane!
Hello, Jane!
Hello, Jane!
Hello, Jane!
Hello, Jane!
*/
我们可以用这些字符串做很多事情!除了像字符串大小写转换这样的基本功能外,Kotlin 还提供了一些函数,当我们想要从中提取信息时,这些函数特别有用。
从字符串中提取信息
提取信息通常意味着去除所有无用信息。例如,我们可能想要检测完全不包含任何实际信息的字符串——即空字符串(不包含任何字符)或空白字符串(仅包含空格)。
要检查我们是否拥有这种类型的字符串,我们可以使用 ` isBlankand`isEmpty函数:
println(" ".isBlank()) // true
println("".isEmpty()) // true
我们还可以使用 ` and`函数方便地将空字符串替换为默认值。在这里,我们可以添加一个代码块,当满足相应条件时,该代码块会为字符串生成默认值:ifBlankifEmpty
val neverBlankString = " ".ifBlank {
"Never blank!"
}
println(neverBlankString) // Never blank!
当一个字符串包含有意义的内容,但这些信息被空格包围时,我们可以使用该trim函数删除字符串开头和结尾的空格,如下所示:
val input = " valuable info "
println(input.trim()) // valuable info
如果文本两侧有一些我们并不在意的其他字符或常用短语,还有三个函数可以帮到我们:`\begin{external}`、`\end{external}`removePrefix和removeSuffix`\ end removeSurrounding{external}`。有了它们,我们可以分别去掉文本开头、结尾和两侧的字符:
val input = "##placeholder##"
println(input.removePrefix("##")) // placeholder##
println(input.removeSuffix("##")) // ##placeholder
println(input.removeSurrounding("##")) // placeholder
从字符串中提取信息的另一种重要方法是使用正则表达式,或者简称为短正则表达式。但这涉及到一个比较大的主题,所以我们会在以后的节目中讨论。
比较字符串
现在我们知道了一些获取只包含我们真正关心的信息的字符串的技巧,我们可以做一些事情,比如将这些字符串相互比较。
相等性检查非常简单,使用双等号即可检查两个字符串是否相同:
val stringA = "astring"
if(stringA == "astring") {
println("Everything cool!")
}
// Everything cool!
但是你知道吗?你还可以根据两个字符串的字母顺序来比较它们。这可以通过使用小于号和大于号来实现。
println("a" < "b") // true
println("c" < "a") // false
当我们想要比较两个字符串而不考虑它们的大小写方式时,我们可以使用 ` compareToand`equals函数,并将ignoreCase参数设置为 `true` true。这不仅比toLowerCase分别对两个字符串调用 `and` 函数更简洁,而且性能也更好:
val input = "QuICK brOWN fox"
println(input.equals("Quick Brown Fox", ignoreCase = true)) // true
将字符串转换为集合
但字符串通常包含多个信息片段,我们希望分别处理这些信息。要将字符串拆分成多个片段,有很多方法可以选择。
通常情况下,这个split函数在这里非常有用:我们可以指定一个字符、单词或其他字符串作为分隔符,该函数会返回一个列表,列出被分隔符分割后的各个字符串片段。例如,考虑以下input字符串,它包含 5 个字母,全部由逗号分隔;:
val input = "A; B; C; D; E"
println(input.split("; ")) // A, B, C, D, E
输出结果是一个包含五个元素的列表。
如果我们只想进行有限次数的分割,也可以将一个参数传递limit给 split 函数。这样,例如,我们最终只会得到三段文本,最后一段是字符串中未被进一步分割的剩余部分。让我们再次考虑之前的例子,这次加上分割次数的限制:
val input = "A; B; C; D; E"
println(input.split("; ", limit = 3)) // A, B, C; D; E
输出结果是一个包含三个元素的列表:A,,B和C; D; E。
对于按行分割字符串这种特殊情况,有一个非常贴切的lines函数,顾名思义,它可以逐行返回文本。它的好处在于,我们不必记住换行符的转义序列。是吗\n?\r\n谁在乎呢,我们有 `lines` 函数!
val input = """
Well this is crazy
I'm a multiline string
So split me maybe?
""".trimIndent()
println(input.lines())
// [Well this is crazy, I'm a multiline string, So split me maybe?]
当然,一旦我们拥有了收藏品,我们就可以做各种各样有趣的事情了。
将字符串视为字符集合
确切地说,即使是单个字符串也像一个集合——因为它本身就是一个字符集合!一方面,这意味着我们可以使用数组运算符来选择特定索引处的字符,这非常有用。但另一方面,这也意味着像mapping、filtering等命令也可以直接作用于字符串。
val input = "Hello, World"
println(input[1]) // e
println(input.filter { it.isUpperCase() }) // HW
我们将在“Kotlin 标准库探索之旅”的后续剧集中探讨这些集合操作——所以,如果您不想错过我未来对这些操作的探索,请务必在 dev.to 上关注@kotlin ,并订阅我们的官方 YouTube 频道,以便在新剧集发布时收到更新通知!
结论
以上就是关于 Kotlin 标准库的第一部分内容。希望您喜欢这篇关于Kotlin 中字符串操作的简要概述。当然,Kotlin 中还有更多功能可供探索。如果您想深入了解可用的字符串 API,可以先阅读 text 文档!
如果您有一些想在未来节目中看到的技巧,请务必在 Twitter 上分享并标记@sebi_io和@kotlin – 也许我们会在本系列的后续节目中看到您的技巧!
希望你学到了一些新东西,也希望你能继续探索 Kotlin 的更多内容!
文章来源:https://dev.to/kotlin/kotlin-standard-library-safari-strings-3lj1