MatchResult
Kotlin 中的 MatchResult 类提供了正则表达式匹配结果的详细信息。主要功能包括获取匹配字符串(value)、匹配位置(range)、捕获组(groups/groupValues)以及解构捕获组(destructured)。通过 next() 方法可以遍历多个匹配项。文中还演示了实用案例(字符串数字处理)和高级特性(非捕获组和命名捕获组)。这些功能使正则表达式操作更灵活高效,适合文本
MatchResult 类
理解 Kotlin 中的 MatchResult 类能帮助你高效地使用正则表达式。
这个类提供了关于匹配操作结果的详细信息。例如,如果你用 find() 函数在字符串中查找匹配,它会返回一个 MatchResult 对象(如果没找到则为 null):
val regex: Regex = """a(\d+)b""".toRegex()
val input = "a123b a4bc"
val firstMatch: MatchResult? = regex.find(input)
其他函数
-
matchAt()和matchEntire()也会返回MatchResult。 -
findAll()会返回一个匹配结果序列(Sequence<MatchResult>)。
MatchResult 的属性和方法
value:完整匹配的字符串
println(firstMatch?.value) // 输出: a123b
这个属性表示整个匹配结果的字符串。
range:匹配在原始字符串中的位置
println(firstMatch?.range) // 输出: 0..4
这个属性表示匹配发生的索引范围。
groups:捕获组集合(MatchGroupCollection)
println(firstMatch?.groups)
// 输出: [MatchGroup(value=a123b, range=0..4), MatchGroup(value=123, range=1..3)]
-
第一个组是整个匹配。
-
后面是括号中捕获的每个组。
groupValues:组对应的值组成的 List<String>
println(firstMatch?.groupValues) // 输出: [a123b, 123]
如果某个组没有捕获内容(如它是可选的且未出现),其值是空字符串。
destructured:解构捕获组值
val regex = """(\d{4})-(\d{2})-(\d{2})""".toRegex()
val input = "2024-01-01"
val secondMatch = regex.find(input)!!
val (year, month, day) = secondMatch.destructured
println("Year: $year") // 输出: Year: 2024
println("Month: $month") // 输出: Month: 01
println("Day: $day") // 输出: Day: 01
destructured 允许你将捕获组解构为变量,变量数必须与捕获组数匹配。
注意:
!!会抛出空指针异常,如果find()返回的是null。
next():获取下一个匹配项
println(firstMatch?.next()?.groupValues) // 输出: [a4b, 4]
与 findAll() 不同,next() 可以更灵活地逐个处理匹配项,适合处理长文本。
实用例子:提高字符串中所有数字的 10%
fun main() {
val regex = Regex("""\d+(\.\d+)?""")
val input = "The price is $12.99 for the first item, and $9.99 for each additional item."
val output = StringBuilder()
var match = regex.find(input)
var lastIndex = 0
while (match != null) {
output.append(input.substring(lastIndex, match.range.first))
val number = match.value.toDouble()
val increasedNumber = number * 1.1
output.append("%.2f".format(increasedNumber))
lastIndex = match.range.last + 1
match = match.next()
}
output.append(input.substring(lastIndex))
println(output)
}
解释:
-
用正则
\d+(\.\d+)?匹配整数或小数。 -
每次找到一个匹配后:
-
加入前面的非数字部分。
-
解析数字并涨价 10%,保留两位小数。
-
使用
next()查找下一个匹配。
-
-
最后补上剩下的文本。
输出:
The price is $14.29 for the first item, and $10.99 for each additional item.
非捕获组:(?:...)
有时我们只想分组但不需要捕获:
val regex = Regex("""\d+(\.\d+)?""")
此时:
Groups: [12.99, .99]
Groups: [9.99, .99]
如果我们不需要 .99 被捕获,可以用非捕获组:
val regex = Regex("""\d+(?:\.\d+)?""")
现在结果是:
Groups: [12.99]
Groups: [9.99]
命名捕获组:(?<name>...)
更可读、更易维护:
val regex = """(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})""".toRegex()
val input = "2023-12-31"
val matchResult = regex.find(input)
println(matchResult?.groups?.get("year")?.value) // 输出: 2023
println(matchResult?.groups?.get("month")?.value) // 输出: 12
println(matchResult?.groups?.get("day")?.value) // 输出: 31
也可使用更简洁写法:
println(matchResult.groups["year"]?.value)
println(matchResult.groups["month"]?.value)
println(matchResult.groups["day"]?.value)
也可以通过索引访问:
println(matchResult.groups[1]?.value) // 同 groups["year"]
更多推荐

所有评论(0)