导读大纲
-
- [1.1 处理字符串和正则表达式](#1.1 处理字符串和正则表达式)
-
- [1.1.1 分割字符串](#1.1.1 分割字符串)
- [1.1.2 正则表达式和三引号字符串](#1.1.2 正则表达式和三引号字符串)
- [1.1.3 多行三引号字符串](#1.1.3 多行三引号字符串)
-
- [IntelliJ IDEA 和 Android Studio 中三重引号字符串内部的语法高亮显示](#IntelliJ IDEA 和 Android Studio 中三重引号字符串内部的语法高亮显示)
1.1 处理字符串和正则表达式
-
Kotlin 字符串与 Java 字符串完全相同
- 可以将 Kotlin 代码中创建的字符串传递给任何 Java 方法
-
Kotlin 通过提供多个有用的扩展函数
- 使处理标准 Java 字符串 变得更加轻松愉快
1.1.1 分割字符串
- 大家应该对字符串的 split 方法并不陌生
- 但Java中的split方法对"."不起作用 "
- 比如 "12.345-6.A".split(".")并期望得到一个数组 [12, 345-6, A]
- 但 Java 的 split 方法会返回一个空数组 ,出现这种情况的原因 是
- split 方法将正则表达式作为参数
- 并根据表达式将字符串拆分成多个字符串
- split 方法将正则表达式作为参数
- 在这里,点(.)是一个正则表达式 , 表示任何字符
- 但Java中的split方法对"."不起作用 "
kotlin
import java.util.Arrays;
public class Example {
public static void main(String[] args){
System.out.println(Arrays.toString("12.345-6 .A".split(".")));
}
}
==============================================
[]
-
Kotlin 隐藏这个令人困惑 的方法,并提供几个名为 split 的重载扩展作为替代
- 比如,接收正则表达式的扩展函数
- 需要 Regex 或 Pattern 类型的参数 值, 而不是字符串
- 比如,接收正则表达式的扩展函数
-
使用点(.)号或破折号(-)来切割字符串
- <1> 调用字符串的toRegex()来明确创建正则表达式
- Kotlin 使用与 Java 完全相同的正则表达式语法
- 这里的模式匹配点或破折号
- 我们将点号转义 以表示我们指的是字面字符,而不是通配符
- <1> 调用字符串的toRegex()来明确创建正则表达式
kotlin
fun main() {
println("12.345-6.A".split("\\.|-".toRegex())) // <1>
// [12, 345, 6, A]
}
- 但对于这种简单的情况,您并不需要使用正则表达式
- Kotlin 中 split 扩展函数的另一个重载
- 将任意数量的分隔符作为纯文本字符串
- 将任意数量的分隔符作为纯文本字符串
- Kotlin 中 split 扩展函数的另一个重载
kotlin
fun main() {
println("12.345-6.A".split(".", "-"))
// [12, 345, 6, A]
}
1.1.2 正则表达式和三引号字符串
-
任务是将文件的全路径名解析 为目录、文件名和扩展名
- 第一种是在String上使用扩展函数
- 第二种是使用正则表达式
-
Kotlin 标准库中包含一些函数
- 用于获取给定分隔符第一次 (或最后一次)出现之前(或之后)的子串
- <1> 文件路径中最后一个斜线符号之前的子串 是外层目录的路径
- <2> 最后一个点之后的子串 是文件扩展名,文件名位于两者之间
kotlin
fun parsePath(fullPath: String) {
val dir = fullPath.substringBeforeLast("/") // <1>
val filePath = fullPath.substringAfterLast("/")
val fileName = filePath.substringBefore(".")
val ext = fullPath.substringAfter(".") // <2>
println(listOf(dir, fileName, ext))
}
fun main() {
parsePath("/Users/w2starts/kotlin/123.md")
// Dir: /Users/w2starts/kotlin, name: 123, ext: md
}
- 正则表达式功能强大 ,但有时在编写之后也很难理解
- <1> 正则表达式是用三引号字符串写成 的
- 在这样的字符串 中,不需要转义任何字符 ,包括反斜杠
- 当你想要匹配字符串中的点(.)号 时
- 可以直接使用"."而不是"\."
- <2> regex.matchEntire函数的结果是可空, 判断匹配成功(结果不是空值 )
- 则将其解构属性的值赋值给相应的变量
- <1> 正则表达式是用三引号字符串写成 的
kotlin
fun parsePathRegex(fullPath: String) {
val regex = """(.+)/(.+)\.(.+)""".toRegex() // <1>
val result = regex.matchEntire(fullPath)
if (result != null) { // <2>
val (dir, fileName, ext) = result.destructured
println("Dir: $dir, name: $fileName, ext: $ext")
}
}
fun main() {
parsePathRegex("/Users/w2starts/kotlin/123.md")
// Dir: /Users/w2starts/kotlin, name: 123, ext: md
}
- 该正则表达式将路径分为三组,中间用斜线和点隔开
- 模式**"."匹配从开头开始的任何字符**
- 因此第一组 (.+)包含最后一条斜线之前的子串
- 这个子串包括斜线之前的所有字符,因为它们匹配"任意字符"模式
- 同样,第二组包含最后一个点之前(最后一个斜线之后)的子串
- 第三组包含剩余部分
- 模式**"."匹配从开头开始的任何字符**
1.1.3 多行三引号字符串
- 使用三引号字符串 的目的不仅仅是为了避免转义字符
- 这种字符串字面量可以包含任何字符 ,包括换行符
- 这样就可以轻松地在程序中嵌入包含换行符的文本
- <1> 多行字符串包含三个引号之间的所有字符
- 这包括用于格式化代码的换行和缩进
- <2> 通过调用 trimIndent ,可以移除字符串中所有行的缩进
- 并移除字符串的首行和末行 (因为它们是空白的)
- 这种字符串字面量可以包含任何字符 ,包括换行符
kotlin
// <1>
val hhh =
"""
| //
|//
|/ \
""".trimIndent() // <2>
fun main() {
println(hhh)
// | //
// |//
// |/ \
}
-
不同的操作系统 使用不同的字符来标记文件的行尾
- Windows 使用 CRLF(回车换行) ,Linux 和 macOS 使用LF(换行)
- 无论使用哪种操作系统 ,Kotlin 都会将 CRLF、LF 和 CR 解释为换行符
-
三引号字符串可以包含换行符 ,但是,你也不能使用特殊字符,比如 \n
- 另一方面,不必转义 ,Windows风格的路径:"C:\Users\w2starts\kotlin"
- 可以写成"""C:\Users\w2starts\kotlin"""
- 您还可以在多行字符串 中使用字符串模板
- 由于多行字符串不支持转义序列
- 如果需要在字符串内容中使用美元符号或转义的 Unicode 符号
- 就必须使用嵌入式表达式
- 如果需要在字符串内容中使用美元符号或转义的 Unicode 符号
- 使用下面形式正确解释转义符号
- 使用 val think = """hhh ${"\uD83E\uDD14"}"""
- 而不能直接使用: val think = """hhh \uD83E\uDD14"""
- 使用 val think = """hhh ${"\uD83E\uDD14"}"""
- 另一方面,不必转义 ,Windows风格的路径:"C:\Users\w2starts\kotlin"
-
测试是多行字符串 在程序中发挥作用的领域之一
- 在测试中,执行会产生多行文本 (如网页片段或其他结构化文本)的操作
- 并将结果与预期输出进行比较 是很常见的
- 多行字符串 是将预期输出作为测试一部分 的完美解决方案
- 无需笨拙地转义 或从外部文件加载文本
- 只需加上一些引号,将预期的 HTML、XML、JSON 或其他输出放在它们之间
- <1> 为了更好地格式化 ,可以使用 trimIndent 函数
- 在测试中,执行会产生多行文本 (如网页片段或其他结构化文本)的操作
kotlin
val expectedPage = """
<html lang="en">
<head>
<title>A page</title>
</head>
<body>
<p>Hello, Kotlin!</p>
</body>
</html>
""".trimIndent()
val expectedObject = """
{
"name": "Sebastian",
"age": 27,
"homeTown": "Munich"
}
""".trimIndent()
fun main() {
println(expectedPage)
println(expectedObject)
}
IntelliJ IDEA 和 Android Studio 中三重引号字符串内部的语法高亮显示
-
对 HTML 或 JSON 等格式化文本使用三引号字符串还有一个额外的好处
- IntelliJ IDEA和Android Studio可以在这些字符串内部提供语法高亮显示
- 要启用高亮功能 ,请将光标置于字符串内
- 然后按 Alt-Enter(或 macOS 上的Option-Return)键
- 或单击浮动的黄色灯泡图标
- 然后选择注入语言或引用
- 比如, 选择字符串中使用的语言类型(如 JSON)
- 多行字符串就会变成语法高亮的 JSON
- 然后按 Alt-Enter(或 macOS 上的Option-Return)键
- 如果您的文本片段碰巧是畸形JSON
- 甚至会在 Kotlin 字符串中收到警告和描述性错误信息
-
默认情况 下, 这种高亮是临时性的
- 要指示集成开发环境 始终以给定语言注入字符串字面量
- 可以使用 @Language("JSON") 注解
- 可以使用 @Language("JSON") 注解
- 有关 IntelliJ IDEA 和 Android Studio 中语言注入
- 要指示集成开发环境 始终以给定语言注入字符串字面量