1. 概述

在本教程中,我们将学习 Kotlin 中几种替换字符串部分内容的方法。这些方法涵盖了从简单字符替换到正则表达式匹配替换等多种场景,适用于不同需求的字符串处理任务。

2. 替换单个字符

Kotlin 提供了 replace(oldChar, newChar) 方法用于替换字符串中的单个字符:

val txt = "I am a robot"
val replaced = txt.replace('a', 'A')
assertEquals("I Am A robot", replaced)

这个方法会将所有匹配的字符替换为新字符。需要注意的是,Kotlin 的字符串是不可变的(immutable),因此所有 replace 方法都会返回一个新字符串,不会修改原字符串。

默认情况下,该方法是区分大小写的。可以通过传入 ignoreCase 参数来关闭区分大小写:

val replaced = txt.replace('i', 'i', ignoreCase = true)
assertEquals("i am a robot", replaced)

小贴士:如果你想替换所有匹配的字符,记得使用这个方法;如果只想替换第一个匹配项,可以使用 replaceFirst

3. 替换子字符串

除了单个字符,也可以替换整个子字符串:

val txt = "I am a robot"
val replaced = txt.replace("robot", "human")
assertEquals("I am a human", replaced)

这个方法同样支持忽略大小写的替换,只需传入布尔参数:

val replaced = txt.replace("i am a", "we are", true)
assertEquals("we are robot", replaced)

⚠️ 注意:替换子字符串时,传入的字符串必须完全匹配才能生效。若需更灵活的匹配方式,建议使用正则表达式。

4. 使用正则表达式替换

Kotlin 支持使用正则表达式进行替换,适用于复杂模式匹配:

val txt = "<div>This is a div tag</div>"
val regex = "</?.*?>".toRegex() // 匹配所有 HTML 标签
val replaced = txt.replace(regex, "")
assertEquals("This is a div tag", replaced)

此外,还可以通过 lambda 表达式动态生成替换内容:

val replaced = txt.replace(regex) {
    it.value.toUpperCase()
}
assertEquals("<DIV>This is a div tag</DIV>", replaced)

小贴士:正则替换非常适合处理 HTML、XML 等结构化文本,建议在处理此类内容时优先考虑。

5. 替换第一个匹配项

如果你只想替换第一个出现的字符或子字符串,可以使用 replaceFirst 方法:

val txt = "I am a robot"
val replaced = txt.replaceFirst('a', 'A')
assertEquals("I Am a robot", replaced)

替换第一个子字符串:

val txt = "42 42"
val replaced = txt.replaceFirst("42", "The answer is")
assertEquals("The answer is 42", replaced)

也可以使用正则表达式进行第一个匹配项的替换:

val txt = "<div>this is a div</div>"
val replaced = txt.replaceFirst("</?.*?>".toRegex(), "")
assertEquals("this is a div</div>", replaced)

6. 替换指定范围的内容

Kotlin 提供了多种方式替换字符串中某个范围的内容。

6.1 数值范围替换

使用 replaceRange(startIndex, endIndex, replacement) 可以替换指定索引范围内的内容:

val txt = "42 is the answer"
val replaced = txt.replaceRange(0, 3, "")
assertEquals("is the answer", replaced)

Kotlin 支持使用范围语法进行替换:

assertEquals("is the answer", txt.replaceRange(0..2, ""))
assertEquals("is the answer", txt.replaceRange(0 until 3, ""))
  • 0..2 是闭区间(包含 0 和 2)
  • 0 until 3 是开区间(包含 0,不包含 3)

6.2 替换“之前”的内容

使用 replaceBefore(charOrString, replacement) 可以替换指定字符或字符串之前的所有内容:

assertEquals("is the answer", txt.replaceBefore('i', ""))
assertEquals("is the answer", txt.replaceBefore("is", ""))

如果没有匹配项,默认返回原字符串:

assertEquals("42 is the answer", txt.replaceBefore("not a match", ""))

可选传入第三个参数作为未匹配时的返回值:

assertEquals("default", txt.replaceBefore("not a match", "", "default"))

还可以使用 replaceBeforeLast() 替换最后一个匹配项之前的内容:

assertEquals("swer", txt.replaceBeforeLast('s', ""))

6.3 替换“之后”的内容

replaceBefore 类似,replaceAfter 可以替换指定字符或字符串之后的内容:

assertEquals("42 i", txt.replaceAfter('i', ""))
assertEquals("42 is", txt.replaceAfter("is", ""))

同样支持 replaceAfterLast() 替换最后一个匹配项之后的内容:

assertEquals("42 is the ans", txt.replaceAfterLast('s', ""))

7. 替换缩进内容

使用 replaceIndent() 可以替换字符串开头的缩进内容:

assertEquals("starts with indent", "    starts with indent".replaceIndent())

也可以指定替换为其他内容:

assertEquals("==> starts with indent", "    starts with indent".replaceIndent("==> "))

8. 其他相关操作

8.1 去除空白(Trim)

Kotlin 提供了多个 trim 系列方法用于去除字符串两端的空白字符:

assertEquals("both ends", "  both ends  ".trim())
assertEquals("both ends", "###both ends!!".trim('#', '!'))

支持传入 lambda 动态判断要去除的字符:

assertEquals("both ends", "#?!both ends@".trim { !it.isLetter() && it != ' ' })

还可以使用 trimStart()trimEnd() 分别处理字符串的开始或结束部分:

assertEquals("just the beginning  ", "  just the beginning  ".trimStart())
assertEquals("  just the ending", "  just the ending  ".trimEnd())

8.2 删除特定内容

使用 removePrefix()removeSuffix() 可以删除字符串的前缀或后缀:

assertEquals("single line comment", "//single line comment".removePrefix("//"))
assertEquals("end of multiline comment", "end of multiline comment*/".removeSuffix("*/"))

使用 removeSurrounding() 可删除前后相同的内容:

assertEquals("some regex", "/some regex/".removeSurrounding("/"))

若前后内容不同,可传入两个参数:

assertEquals("multiline comment", "/*multiline comment*/".removeSurrounding("/*", "*/"))

8.3 删除指定范围内容

使用 removeRange() 可删除指定索引范围的内容:

assertEquals("a robot", "I'm a robot".removeRange(0..3))
assertEquals("a robot", "I'm a robot".removeRange(0 until 4))

8.4 截取部分字符串

使用 take() 系列方法可以截取字符串部分内容:

assertEquals("42", txt.take(2))
assertEquals("answer", txt.takeLast(6))
assertEquals("42", txt.takeWhile { it != ' ' })
assertEquals("answer", txt.takeLastWhile { it != ' ' })

9. 总结

Kotlin 提供了丰富而灵活的字符串替换 API,涵盖了从字符、子字符串到正则表达式、范围操作等多种场景。无论是简单的替换,还是复杂的模式匹配,都能找到合适的函数来完成任务。

所有示例代码均可在 GitHub 上查看


原始标题:Functions for Replacing Part of a String in Kotlin