Kotlin 处理字符串和正则表达式(二十一)

导读大纲

    • [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 处理字符串和正则表达式

  1. Kotlin 字符串与 Java 字符串完全相同

    • 可以将 Kotlin 代码中创建的字符串传递给任何 Java 方法
  2. Kotlin 通过提供多个有用的扩展函数

    • 使处理标准 Java 字符串 变得更加轻松愉快

1.1.1 分割字符串

  1. 大家应该对字符串的 split 方法并不陌生
    • 但Java中的split方法对"."不起作用 "
      1. 比如 "12.345-6.A".split(".")并期望得到一个数组 [12, 345-6, A]
    • Java 的 split 方法会返回一个空数组 ,出现这种情况的原因
      1. 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(".")));
    }
}
==============================================
[]
  1. Kotlin 隐藏这个令人困惑 的方法,并提供几个名为 split 的重载扩展作为替代

    • 比如,接收正则表达式的扩展函数
      1. 需要 Regex 或 Pattern 类型的参数 值, 而不是字符串
  2. 使用点(.)号或破折号(-)来切割字符串

    • <1> 调用字符串的toRegex()来明确创建正则表达式
      1. Kotlin 使用与 Java 完全相同的正则表达式语法
      2. 这里的模式匹配点或破折号
        • 我们将点号转义 以表示我们指的是字面字符,而不是通配符
kotlin 复制代码
fun main() {
    println("12.345-6.A".split("\\.|-".toRegex())) // <1>
    // [12, 345, 6, A]
}
  1. 但对于这种简单的情况,您并不需要使用正则表达式
    • Kotlin 中 split 扩展函数的另一个重载
      1. 将任意数量的分隔符作为纯文本字符串
kotlin 复制代码
fun main() {
    println("12.345-6.A".split(".", "-"))
    // [12, 345, 6, A]
}

1.1.2 正则表达式和三引号字符串

  1. 任务是将文件的全路径名解析目录、文件名和扩展名

    • 第一种是在String上使用扩展函数
    • 第二种是使用正则表达式
  2. 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. 正则表达式功能强大 ,但有时在编写之后也很难理解
    • <1> 正则表达式是用三引号字符串写成
      1. 在这样的字符串 中,不需要转义任何字符 ,包括反斜杠
      2. 当你想要匹配字符串中的点(.)号
        • 可以直接使用"."而不是"\."
    • <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. 因此第一组 (.+)包含最后一条斜线之前的子串
      2. 这个子串包括斜线之前的所有字符,因为它们匹配"任意字符"模式
    • 同样,第二组包含最后一个点之前(最后一个斜线之后)的子串
    • 第三组包含剩余部分

1.1.3 多行三引号字符串

  1. 使用三引号字符串 的目的不仅仅是为了避免转义字符
    • 这种字符串字面量可以包含任何字符 ,包括换行符
      1. 这样就可以轻松地在程序中嵌入包含换行符的文本
    • <1> 多行字符串包含三个引号之间的所有字符
      1. 包括用于格式化代码的换行和缩进
    • <2> 通过调用 trimIndent ,可以移除字符串中所有行的缩进
      1. 移除字符串的首行和末行 (因为它们是空白的)
kotlin 复制代码
// <1>
val hhh =                       
    """
| //
|//
|/ \
""".trimIndent()                   // <2>
fun main() {
    println(hhh)
    // | //
    // |//
    // |/ \
}
  1. 不同的操作系统 使用不同的字符来标记文件的行尾

    • Windows 使用 CRLF(回车换行) ,Linux 和 macOS 使用LF(换行)
    • 无论使用哪种操作系统 ,Kotlin 都会将 CRLF、LF 和 CR 解释为换行符
  2. 三引号字符串可以包含换行符 ,但是,你也不能使用特殊字符,比如 \n

    • 另一方面,不必转义 ,Windows风格的路径:"C:\Users\w2starts\kotlin"
      1. 可以写成"""C:\Users\w2starts\kotlin"""
    • 您还可以在多行字符串使用字符串模板
    • 由于多行字符串不支持转义序列
      1. 如果需要在字符串内容中使用美元符号或转义的 Unicode 符号
        • 必须使用嵌入式表达式
    • 使用下面形式正确解释转义符号
      1. 使用 val think = """hhh ${"\uD83E\uDD14"}"""
        • 不能直接使用: val think = """hhh \uD83E\uDD14"""
  3. 测试是多行字符串 在程序中发挥作用的领域之一

    • 在测试中,执行会产生多行文本 (如网页片段或其他结构化文本)的操作
      1. 将结果与预期输出进行比较很常见
    • 多行字符串将预期输出作为测试一部分完美解决方案
      1. 无需笨拙地转义从外部文件加载文本
      2. 只需加上一些引号,将预期的 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 中三重引号字符串内部的语法高亮显示
  1. 对 HTML 或 JSON 等格式化文本使用三引号字符串还有一个额外的好处

    • IntelliJ IDEA和Android Studio可以在这些字符串内部提供语法高亮显示
    • 启用高亮功能 ,请将光标置于字符串内
      1. 然后按 Alt-Enter(或 macOS 上的Option-Return)键
        • 单击浮动的黄色灯泡图标
      2. 然后选择注入语言或引用
        • 比如, 选择字符串中使用的语言类型(如 JSON)
      3. 多行字符串就会变成语法高亮的 JSON
    • 如果您的文本片段碰巧是畸形JSON
      1. 甚至会在 Kotlin 字符串中收到警告和描述性错误信息
  2. 默认情况 下, 这种高亮是临时性

相关推荐
用余生去守护2 分钟前
python报错系列(16)--pyinstaller ????????
开发语言·python
yuanbenshidiaos5 分钟前
c++---------数据类型
java·jvm·c++
数据小爬虫@7 分钟前
利用Python爬虫快速获取商品历史价格信息
开发语言·爬虫·python
向宇it9 分钟前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
Lojarro23 分钟前
【Spring】Spring框架之-AOP
java·mysql·spring
莫名其妙小饼干25 分钟前
网上球鞋竞拍系统|Java|SSM|VUE| 前后端分离
java·开发语言·maven·mssql
十年一梦实验室35 分钟前
【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
开发语言·c++·线性代数·矩阵
isolusion37 分钟前
Springboot的创建方式
java·spring boot·后端
最爱番茄味44 分钟前
Python实例之函数基础打卡篇
开发语言·python
zjw_rp1 小时前
Spring-AOP
java·后端·spring·spring-aop