Skip to content

文本处理与正则表达式

源:Kotlin standard library - Text

Kotlin 对字符串的操作进行了极大的增强,通过扩展函数解决了 Java String 类中许多不便之处。同时,Kotlin 的 Regex 类提供了更符合现代编程习惯的正则表达式接口。

字符串构建与控制

buildString

类似 buildListbuildString 提供了一个简单的 DSL 来构建复杂的字符串,内部使用 StringBuilder 实现。

kotlin
val message = buildString {
    append("Hello, ")
    appendLine("World!")
    append("Count: ")
    append(10)
}

多行字符串格式化

Kotlin 的原始字符串 (""") 非常适合编写多行文本,但缩进处理往往是个难题。

kotlin
// 自动检测并去除公共的最小缩进
val code = """
    fun main() {
        println("Hello")
    }
""".trimIndent()
kotlin
// 使用边界符(默认 |)控制缩进
val query = """
    |SELECT * FROM users
    |WHERE id = ?
    |LIMIT 10
""".trimMargin()

实用扩展函数

Kotlin 提供了许多意图清晰的函数,避免了繁琐的 indexOfsubstring 手动计算。

kotlin
val path = "src/main/kotlin/App.kt"

// 获取前缀/后缀
println(path.substringBeforeLast("/")) // "src/main/kotlin"
println(path.substringAfterLast("."))  // "kt"

// 补全
println("42".padStart(4, '0')) // "0042"

// 替换
println("apple".replaceFirstChar { it.uppercase() }) // "Apple"

正则表达式 (Regex)

Kotlin 的 Regex 类将正则表达式的操作封装得非常直观,支持具名捕获组和解构。

定义与匹配

kotlin
val emailRegex = """[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+""".toRegex()

val isEmail = emailRegex.matches("test@example.com")

强大的解构匹配 (Destructuring)

这是 Kotlin 正则最优雅的功能之一。你可以直接将匹配结果解构到变量中。

kotlin
val dateRegex = """(\d{4})-(\d{2})-(\d{2})""".toRegex()
val input = "2023-12-25"

val matchResult = dateRegex.find(input)

if (matchResult != null) {
    // ⭐️ 直接解构捕获组
    val (year, month, day) = matchResult.destructured
    println("Year: $year, Month: $month, Day: $day")
}

具名捕获组 Kotlin 1.9+

kotlin
val regex = """(?<areaCode>\d{3})-(?<number>\d{7})""".toRegex()
val match = regex.find("010-1234567")

if (match != null) {
    println(match.groups["areaCode"]?.value) // "010"
}

类型安全转换

Kotlin 提供了许多 toXxxOrNull 函数,避免了直接转换时抛出异常。

kotlin
val input = "123a"

val number: Int? = input.toIntOrNull() // 返回 null 而不是崩溃

val price: Double = "9.99".toDoubleOrNull() ?: 0.0

字符处理 (Char)

Kotlin 将 Char 视为非数字类型,并提供了丰富的判断函数。

kotlin
val c = 'A'

println(c.isDigit())        // false
println(c.isLetter())       // true
println(c.isWhitespace())   // false
println(c.isUpperCase())    // true

工程建议

  1. 避免过度正则:对于简单的逻辑(如判断包含、前后缀),优先使用 contains, startsWith, substringBefore 等函数,它们的执行效率远高于正则表达式。
  2. 正则预编译:如果你在循环或频繁调用的函数中使用正则,请将其定义为类的 companion object 属性或顶层属性,避免重复调用 toRegex()
  3. 合理使用 trimMargin:在编写 SQL 或 HTML 模板字符串时,始终配合 trimMargin() 使用,以保证代码排版整齐且输出内容符合预期。