由字符组成的一串字符序列,称为“字符串”,在前面的章节中也多次用到了字符串,本章将重点介绍。
Kotlin中的字符串字面量有两种:
普通字符串,采用双引号(")包裹起来的字符串。
原始字符串(raw string),采用三个双引号(""")包裹起来的字符串。
7.1.1 普通字符串
普通字符串字面量与Java语言采用双引号(")包裹起来的字符串,大部分计算机语言都是采用这种方式表示字符串。下面示例都是普通字符串字面量:
“Hello World” ①
“\u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064” ②
“世界你好” ③
“Hello \nWorld” ④
“A” ⑤
“” ⑥
Kotlin中的字符采用Unicode编码,所以Kotlin字符串可以包含中文等亚洲字符,见代码第③行的"世界你好"字符串。代码第②行的字符串是用Unicode编码表示的字符串,事实上它表示的也是"Hello World"字符串,可通过println函数将Unicode编码表示的字符串输出到控制台,则会看到Hello World字符串。普通字符串字面量为了包含一些特殊的字符,例如换行,则需要转义符,代码第④行"Hello \nWorld"包含了一个换行符,\n是换行转义符,Kotlin转义符参考表6-4所示。
单个字符如果用双引号括起来,那它表示的是字符串,而不是字符了,见代码第⑤行的"A"是表示字符串A,而不是字符A。
7.1.2 原始字符串
原始字符串(raw string)字面量采用三个双引号(""")包裹起来的字符串,原始字符串可以包含任何的字符,而不需要转移,所以也不能包含转义字符。示例如下:
“Hello\nWorld” ①
“”“Hello
World”"" ②
代码第①行和第②行表示相同内容的字符串,代码①行是普通字符串字面量表示在Hello和World中间包含转义换行符,代码第②行是原始字符串字面量可以在Hello和World之间直接换行。
示例代码如下:
//代码文件:chapter7/src/com/a51work6/section1/ch7.1.1.kt
package com.a51work6.section1
fun main(args: Array) {
val s1 =""
val s2 = "Hello World"
val s3 ="\u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064"
println(s2 == s3) //输出结果为true
val s4 = "Hello\nWorld"
val s5 = """Hello
World"""
println(s4 == s5) //输出结果为true
val s6 ="""Hello\nWorld"""
println(s6)
}
运行结果:
true
true
Hello\nWorld
上述代码中s2和s3是两个内容相同的字符串,这说明无论采用的是Unicode编码还是普通字符都是相同。s4和s5是也两个内容相同的字符串,这说明无论采用的是普通字符串字面量表示,还是采用原始字面量表示都是相同的。
其中==是比较两个字符串。
在Kotlin中默认的字符串类是String,String是一种不可变字符串,当字符串进行拼接等修改操作时,会创建新的字符串对象,而可变字符串不会创建新对象。在Kotlin中可变字符串类是StringBuilder。
7.2.1 String
本节先介绍不可变字符串String类的使用。Kotlin提供的不可变字符串类是kotlin.String,获得String对象可以有两种方式:
使用字符串字面量赋值。
使用转换函数。
直接使用字符串字面量赋值前面已经使用过了。下面重点介绍转换函数,这些函数都是顶层函数不需要对象就可以直接使用。
1.字节数组转换成字符串函数:
fun String(
bytes:ByteArray, //要转换的字节数组
offset: Int, //字节数组开始索引,该参数可以省略。
length: Int, //转换字节的长度,该参数可以省略。
charset:Charset //解码字符集 ,该参数可以省略。
): String
2.字符数组转换成字符串函数:
fun String(
chars:CharArray, //要转换的字符数组
offset: Int, //字符数组开始索引,该参数可以省略。
length: Int //转换字符的长度,该参数可以省略。
): String
3.可变字符串StringBuilder转换成字符串函数:
fun String(stringBuilder: StringBuilder): String
示例代码如下:
//代码文件:chapter7/src/com/a51work6/ch7.2.kt
package com.a51work6
fun main(args: Array) {
val chars = charArrayOf('a', 'b','c', 'd', 'e') //创建字符数组 ①
val s1 = String(chars) // 通过字符数组获得字符串对象 ②
val s2 = String(chars, 1, 4) // 通过子字符数组获得字符串对象 ③
println("s1 = " + s1) //输出结果s1 = abcde
println("s2 = " + s2) //输出结果s2 = bcde
val bytes = byteArrayOf(97, 98,99) //创建字节数组 ④
val s3 = String(bytes) // 通过字节数组获得字符串对象 ⑤
val s4 = String(bytes, 1, 2) // 通过子字节数组获得字符串对象 ⑥
println("s3 = " + s3) //输出结果s3 = abc
println("s4 = " + s4) //输出结果s4 = bc
}
上述代码第①行是使用charArrayOf函数创建字符数组。代码第②行是将chars数组中的全部字符用来创建字符串。代码第③行是将chars数组中的部分字符用来创建字符串。
代码第④行是使用byteArrayOf函数创建字节符数组。代码第⑤行是采用默认字符集将bytes数组中的全部字节用来创建字符串。代码第⑥行是采用默认字符集将bytes数组中的部分字节用来创建字符串。
字符串在程序代码中应用十分广泛,下面通过几个方面介绍一下在Kotlin中如何使用字符串。本节所介绍的字符串是String类及相关函数使用。
7.2.2 字符串拼接
String字符串虽然是不可变字符串,但也可以进行拼接只是会产生一个新的对象。String字符串拼接可以使用+和+=运算符。+和+=运算符是可以连接任何类型数据拼接成为字符串。
字符串拼接示例如下:
//代码文件:chapter7/src/com/a51work6/section2/ch7.2.2.kt
package com.a51work6.section2
fun main(args: Array) {
val s1 = "Hello"
// 使用+运算符连接
val s2 = s1 + " " ①
val s3 = s2 + "World" ②
println(s3)//Hello World
var s4 = "Hello"
// 使用+运算符连接,支持+=赋值运算符
s4 += " " ③
s4 += "World" ④
println(s4)//Hello World
val age = 18
val s5 = "她的年龄是" + age + "岁。" ⑤
println(s5)//她的年龄是18岁。
val score = 'A'
val s6 = "她的英语成绩是" + score ⑥
println(s6)//她的英语成绩是A
val now = java.util.Date()
//对象拼接自动调用toString()函数
val s7 = "今天是:" + now ⑦
println(s7)
}
输出结果:
Hello World
Hello World
她的年龄是18岁。
她的英语成绩是A
今天是:Thu May 25 16:25:40 CST 2017
上述代码第①②行使用+运算符进行字符串的拼接,其中产生了三个对象。代码第③④行是使用+=赋值运算符,本质上也是+运算符进行拼接。
代码第⑤和第⑥行是使用+运算符,将字符串与其他类型数据进行的拼接。代码第⑦行是与对象可以进行拼接,Kotlin中所有对象都有一个toString函数,该函数可以将对象转换为字符串,拼接过程会调用该对象的toString函数,将该对象转换为字符串后再进行拼接。代码第⑦行的java.util.Date类是来自于Java的日期类。
7.2.3 字符串模板
字符串拼接对于字符串追加和连接是比较方便,但是如果字符串中有很多表达式结果需要连接起来,采用字符串拼接就有点力不从心了。此时可以使用字符串模板,它是可以将一些表达式结果在运行时插入到字符串中。
字符串模板是以$开头,语法如下:
$变量或常量
${表达式} //任何表达式,也可以是单个变量或常量
示例代码:
//代码文件:chapter7/src/com/a51work6/section2/ch7.2.3.kt
package com.a51work6.section2
fun main(args: Array) {
val age = 18
val s1 = "她的年龄是${age}岁。" //使用表达式形式模板 ①
println(s1)//她的年龄是18岁。
val score = 'A'
val s2 = "她的英语成绩是$score" //使用变量形式模板 ②
println(s2)//她的英语成绩是A
val now =java.util.Date()
val s3 = "今天是:${now.year + 1900}年${now.month}月${now.day}日" ③
println(s3)
val s4 ="""今天是:
${now.year+ 1900}年
${now.month}月
${now.day}日"""//在原始字符串中使用字符串模板 ④
println(s4)
}
运行结果如下:
她的年龄是18岁。
她的英语成绩是A
今天是:2017年9月3日
今天是:
2017年
9月
3日
上述代码第①行是使用表达式形式字符串模板 a g e , 代 码 第 ② 行 是 使 用 变 量 形 式 模 板 {age},代码第②行是使用变量形式模板 age,代码第②行是使用变量形式模板score。代码第③行的字符串模板中包含了多个字符串模板。代码第④行是在原始字符串中也可以使用字符串模板,可见于不同字符串没有区别。
7.2.4 字符串查找
在给定的字符串中查找字符或字符串是比较常见的操作。在String类中提供了indexOf和lastIndexOf函数用于查找字符或字符。indexOf函数从前往后查找字符或字符串,返回第一次找到字符或字符串所在处的索引,没有找到返回-1。lastIndexOf函数从后往前查找字符或字符串,返回第一次找到字符或字符串所在处的索引,没有找到返回-1。
根据所查找的是字符还是字符串indexOf函数有两个版本,说明如下:
1.查找字符的indexOf函数:
fun String.indexOf(
char: Char, //要查找的字符
startIndex: Int= 0, //指定查找开始的索引
ignoreCase:Boolean = false //是否忽略大写小进行匹配
): Int
2. 查找字符串的indexOf函数:
fun String.indexOf(
string: String,
//要查找的字符串
startIndex: Int= 0, //指定查找开始的索引
ignoreCase:Boolean = false //是否忽略大写小进行匹配
): Int
上述两个版本的函数startIndex和ignoreCase参数都有提供了默认值,因此都可以省略。startIndex默认值为0,表示从头开始查找。ignoreCase默认值为false,表示不忽略大写小进行匹配。
lastIndexOf也有类似于indexOf的两个版本的函数,说明如下:
1.查找字符的lastIndexOf函数:
fun String.lastIndexOf (
char: Char, //要查找的字符
startIndex: Int= 0, //指定查找开始的索引
ignoreCase:Boolean = false //是否忽略大写小进行匹配
): Int
2. 查找字符串的lastIndexOf函数:
fun String.lastIndexOf (
string: String,
//要查找的字符串
startIndex: Int= 0, //指定查找开始的索引
ignoreCase:Boolean = false //是否忽略大写小进行匹配
): Int
字符串查找示例代码如下:
//代码文件:chapter7/src/com/a51work6/section2/ch7.2.4.kt
package com.a51work6.section2
fun main(args: Array) {
val sourceStr ="There is a string accessing example."
val len =sourceStr.length //获得字符串长度
val ch = sourceStr[16] //获得索引位置16的字符
//查找字符和子字符串
val firstChar1= sourceStr.indexOf('r')
val lastChar1 =sourceStr.lastIndexOf('r',ignoreCase = true)
val firstStr1 =sourceStr.indexOf("ing")
val lastStr1 =sourceStr.lastIndexOf("ing")
val firstChar2= sourceStr.indexOf('e', 15)
val lastChar2 =sourceStr.lastIndexOf('e', 15)
val firstStr2 =sourceStr.indexOf("ing", 5)
val lastStr2 =sourceStr.lastIndexOf("ing", 5)
println("原始字符串:" +sourceStr)
println("字符串长度:" + len)
println("索引16的字符:" + ch)
println("从前往后查找r字符,第一次找到它所在索引:" + firstChar1)
println("从后往前查找r字符,第一次找到它所在索引:" + lastChar1)
println("从前往后查找ing字符串,第一次找到它所在索引:" + firstStr1)
println("从后往前查找ing字符串,第一次找到它所在索引:" + lastStr1)
println("从索引为15位置开始,从前往后查找e字符,第一次找到它所在索引:" + firstChar2)
println("从索引为15位置开始,从后往前查找e字符,第一次找到它所在索引:" + lastChar2)
println("从索引为5位置开始,从前往后查找ing字符串,第一次找到它所在索引:" + firstStr2)
println("从索引为5位置开始,从后往前查找ing字符串,第一次找到它所在索引:" + lastStr2)
}
输出结果:
原始字符串:There is a string accessing example.
字符串长度:36
索引16的字符:g
从前往后查找r字符,第一次找到它所在索引:3
从后往前查找r字符,第一次找到它所在索引:13
从前往后查找ing字符串,第一次找到它所在索引:14
从后往前查找ing字符串,第一次找到它所在索引:24
从索引为15位置开始,从前往后查找e字符,第一次找到它所在索引:21
从索引为15位置开始,从后往前查找e字符,第一次找到它所在索引:4
从索引为5位置开始,从前往后查找ing字符串,第一次找到它所在索引:14
从索引为5位置开始,从后往前查找ing字符串,第一次找到它所在索引:-1
sourceStr字符串索引如图7-1所示。上述字符串查找函数比较类似,这里重点解释一下sourceStr.indexOf(“ing”,
5)和sourceStr.lastIndexOf(“ing”,
5)表达式。从图7-1可见ing字符串出现过两次,索引分别是14和24。sourceStr.indexOf(“ing”,
5)表达式从索引为5的字符(" “)开始从前往后查找,结果是找到第一个ing(索引为14),返回值为14。sourceStr.lastIndexOf(“ing”,
5)表达式从索引为5的字符(” ")开始从后往前查找,没有找到,返回值为-1。
7.2.5 字符串比较
字符串比较是常见的操作,包括比较相等、比较大小、比较前缀和后缀等。
1.比较相等
在字符串比较时默认是比较两个字符串中内容是否相等,使用equals函数、运算符和!=运算符进行比较,事实上和!=运算符在底层还是调用equals函数进比较的。equals函数说明如下:
fun String?.equals(
other: String?,
ignoreCase:Boolean = false
): Boolean
equals函数可以进行两个可空String类型(String?)比较。ignoreCase: Boolean = false说明可忽略大小写,而使用==和!=运算符进行比较时不能忽略大小写。
2. 比较大小
有时不仅需要知道是否相等,还要知道大小,String提供的比较大小的函数是compareTo。compareTo函数说明如下:
fun String.compareTo(
other: String,
ignoreCase:Boolean = false
): Int
compareTo函数按字典顺序比较两个字符串。如果当前字符串等于参数字符串,则返回值 0;如果当前字符串位于参数字符串之前,则返回一个小于 0 的值;如果当前字符串位于参数字符串之后,则返回一个大于 0 的值。
3. 比较前缀和后缀
fun String.startsWith(
prefix: String,
ignoreCase:Boolean = false
): Boolean
startsWith函数是测试此字符串是否以指定的前缀开始。
fun String.endsWith(
suffix: String,
ignoreCase:Boolean = false
): Boolean
endsWith函数是测试此字符串是否以指定的后缀结束。
字符串比较示例代码如下:
//代码文件:chapter7/src/com/a51work6/section2/ch7.2.5.kt
package com.a51work6.section2
fun main(args: Array) {
val s1 = "Hello"
val s2 = "Hello"
// 比较字符串内容是否相等
println(s1.equals(s2)) //输出true
println(s1 == s2) //输出true
val s3 = “HELlo”
// 忽略大小写比较字符串内容是否相等
println(s1.equals(s3, ignoreCase =true)) //输出true
println(s1 == s3) //输出false ①
// 比较大小
val s4 = "java"
val s5 = "Kotlin"
println(s4.compareTo(s5)) // 输出31 ②
println(s4.compareTo(s5, ignoreCase =true)) // 输出-1 ③
// 判断文件夹中文件名
val docFolder =
arrayOf(“java.docx”, “JavaBean.docx”,
“Objecitve-C.xlsx”, “Swift.docx”)
var wordDocCount = 0
// 查找文件夹中Word文档个数
for (doc in docFolder) {
// 比较后缀是否有.docx字符串
if(doc.endsWith(".docx")) {
wordDocCount++
}
}
println("文件夹中Word文档个数是: " + wordDocCount)
var javaDocCount = 0
// 查找文件夹中Java相关文档个数
for (doc in docFolder) {
// 比较前缀是否有java字符串
if(doc.startsWith("java", ignoreCase = true)) {
javaDocCount++
}
}
println("文件夹中Java相关文档个数是:" + javaDocCount)
}
输出结果:
true
true
true
false
31
-1
文件夹中Word文档个数是: 3
文件夹中Java相关文档个数是:2
上述代码第①行的中的==运算符比较字符串比能忽略大小写。代码第②行的compareTo函数返回值大于0,说明s4大于s5。代码③行是忽略大小写,compareTo函数返回值小于0,说明忽略大小写后s4小于s5。
7.2.6 字符串截取
Kotlin中字符串截取函数是substring,主要有三个版本。
1.指定整数区间截取字符串函数:
String.substring(range: IntRange): String
2. 从指定索引startIndex开始截取一直到字符串结束的子字符串:
fun String.substring(startIndex: Int): String
3. 从指定索引startIndex开始截取直到索引endIndex - 1处的字符,注意包括索引为startIndex处的字符,但不包括索引为endIndex处的字符:
fun String.substring(startIndex: Int, endIndex: Int):
String
字符串截取示例代码如下:
//代码文件:chapter7/src/com/a51work6/section2/ch7.2.6.kt
package com.a51work6.section2
fun main(args: Array) {
val sourceStr = "There is a string accessing example."
// 截取example.子字符串
val subStr1 = sourceStr.substring(28)
// 截取string子字符串
val subStr2 = sourceStr.substring(11,17)
// 参数是区间
val subStr3 =sourceStr.substring(11..17)
println(subStr1)
println(subStr2)
println(subStr3)
}
输出结果:
subStr1 = example.
subStr2 = string
上述sourceStr字符串索引参考图7-1所示。代码第①行是截取example.子字符串,从图7-1可见e字符索引是28, 从索引28字符截取直到sourceStr结尾。代码第②行是截取string子字符串,从图7-1可见,s字符索引是11,g字符索引是16,endIndex参数应该17。
可变字符串在追加、删除、修改、插入和拼接等操作不会产生新的对象。
7.3.1 StringBuilder
Kotlin提供不可变字符串类是kotlin.text.StringBuilder,StringBuilder的中构造函数有4个:
1.StringBuilder()。创建字符串内容是空的StringBuilder对象,初始容量默认为16个字符。
2.StringBuilder(seq: CharSequence)。指定CharSequence字符串创建StringBuilder对象。CharSequence接口类型,它的实现类有:String和StringBuilder等,所以参数seq可以是String和StringBuilder等类型。
3.StringBuilder(capacity: Int)。创建字符串内容是空的StringBuilder对象,初始容量由参数capacity指定的。
4.StringBuilder(str: String)。指定String字符串创建StringBuilder对象。
字符串长度和字符串容量示例代码如下:
//代码文件:chapter7/src/com/a51work6/section3/ch7.3.1.kt
package com.a51work6.section3
fun main(args: Array) {
//-----------------------------------
// 字符串长度length和字符串缓冲区容量capacity
val sbuilder1 =StringBuilder()
println(“字符串长度:” + sbuilder1.length)
println(“字符串容量:” +sbuilder1.capacity())
val sbuilder2 =StringBuilder("Hello")
println("字符串长度:" +sbuilder2.length)
println("字符串容量:" +sbuilder2.capacity())
// 字符串缓冲区初始容量是16,超过之后会扩容
val sbuilder3 =StringBuilder()
for (i in0..16) {
sbuilder3.append(8)
}
println(“字符串长度:” +sbuilder3.length)
println(“字符串容量:” +
sbuilder3.capacity())
}
输出结果:
字符串长度:0
字符串容量:16
字符串长度:5
字符串容量:21
字符串长度:17
字符串容量:34
7.3.2 字符串追加、插入、删除和替换
StringBuilder在提供了很多修改字符串的函数,追加、插入、删除和替换等,对应的函数分别是append、insert、delete和replace函数,这些函数不会产生新的字符串对象,而且它们的返回值还是StringBuilder。
字符串追加示例代码如下:
//代码文件:chapter7/src/com/a51work6/section3/ch7.3.2.kt
package com.a51work6.section3
fun main(args: Array) {
//添加字符串、字符
val sbuilder1 =StringBuilder("Hello") ①
sbuilder1.append(" ").append(“World”) ②
sbuilder1.append(’.’) ③
println(sbuilder1)
val sbuilder2 =StringBuilder()
val obj: Any? =null
//添加布尔值、转义符和空对象
sbuilder2.append(false).append(’\t’).append(obj) ④
println(sbuilder2)
//添加数值
val sbuilder3 =StringBuilder()
for (i in 0..9){
sbuilder3.append(i)
}
println(sbuilder3)
// 插入字符串
sbuilder3.insert(4, “Kotlin”) ⑤
println(sbuilder3)
// 删除字符串
sbuilder3.delete(1, 2) ⑥
println(sbuilder3)
// 替换字符串
sbuilder3.replace(3, 9, “A”) ⑦
println(sbuilder3)
}
运行结果:
Hello World.
false null
0123456789
0123Kotlin456789
023Kotlin456789
023A456789
上述代码第①行是创建一个包含Hello字符串StringBuilder对象。代码第②行是两次连续调用append函数,由于所有的append函数都返回StringBuilder对象,所有可以连续调用该函数,这种写法比较简洁。如果连续调用append函数不行喜欢,可以append函数占一行,见代码第③行。代码第④行连续追加了布尔值、转义符和空对象,需要注意的是布尔值false转换为false字符串,空对象null也转换为"null"字符串。
代码第⑤行是插入字符串,第一个参数是插入字符串的位置,在此位置之前插入字符串,第二个参数是要参数的字符串。
代码第⑥行是删除字符串,第一个参数开始删除的位置索引,包括此索引的字符。第二个参数结束删除位置索引,不包括此索引的字符。本例中删除"1"字符。
代码第⑦行是替换字符串,第一个参数开始替换的位置索引,包括此索引的字符。第二个参数结束替换位置索引,不包括此索引的字符。第三个参数是要替换的新字符串。本例中用"A"替换"Kotlin"字符串。
7.4 正则表达式
正则表达式(英语为“regular expression”,在代码中常简写为regex、regexp或RE)是预先定义好一个“规则字符串”,这个“规则字符串”可用于匹配、过滤、检索和替换那些符合“规则”的文本。
7.4.1 Regex类
Kotlin提供的正则表达式类是kotlin.text.Regex。创建Regex对象可以通过如下两种方式:
o 通过构造函数创建。Regex 默认构造函数是Regex(pattern: String),其中pattern是正则表达式模式字符串。
o 使用toRegex()扩展函数。String提供扩展函数toRegex()返回Regex对象。
下面是一个验证邮箱格式的有效性示例,代码如下:
//代码文件:chapter7/src/com/a51work6/section4/ch7.4.1.kt
package com.a51work6.section4
fun main(args: Array) {
val pattern ="""\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}""" ①
val string ="[email protected]" ②
//val regex =Regex(pattern) ③
val regex =pattern.toRegex() ④
println(regex.matches(string)) ⑤
}
上述代码第①行是在http://www.regexlib.com/网站找到一个验证邮箱的正则表达式模式字符串。
代码第②行是要验证的字符串。代码第③行的通过构造函数创建Regex对象,代码第④行通过toRegex函数创建Regex对象。代码第⑤行是通过Regex的matches函数验证输入的字符串是否与正则表达式匹配。
7.4.2 字符串匹配
正则表达式通过字符串匹配能够字符串格式的有效性,例如:邮箱、日期、电话号码等格式的有效性。Regex通过的正则表达式字符串匹配相关函数如下:
1.matches(input: CharSequence):
Boolean。精确匹配函数,测试输入字符串是否完全匹配正则表达式模式。
2.containsMatchIn(input: CharSequence): Boolean。包含匹配函数,测试输入字符串是否部分匹配正则表达式模式。
示例代码如下:
//代码文件:chapter7/src/com/a51work6/section4/ch7.4.1.kt
package com.a51work6.section4
fun main(args: Array) {
//全部是数字模式
val regex =Regex("""\d+""") ①
val input1 ="1000"
val input2 ="¥1000"
println(regex.matches(input1))//true ②
println(regex.matches(input2))//false ③
println(regex.containsMatchIn(input1))//true
println(regex.containsMatchIn(input2))//true ④
}
上述代码第①行声明正则表达式模式字符串,该模式是全部数字。代码第②行测试input1字符串返回true,代码第③行是测试input2字符串返回false,同样字符串input2使用containsMatchIn函数返回ture,见代码第④行,containsMatchIn函数只要是部分匹配则会返回true。
7.4.3 字符串查找
正则表达式还经常用于字符串查找。Regex中字符串查找相关函数如下:
1.find(input: CharSequence, startIndex: Int): MatchResult?。查找第一个匹配模式的字符串,返回MatchResult?类型。
2.findAll(input: CharSequence, startIndex: Int): Sequence。查找所有匹配模式的字符串,返回Sequence类型,Sequence是可进行迭代集合类型,其中可以放置的元素是MatchResult类型。
示例代码如下:
//代码文件:chapter7/src/com/a51work6/section4/ch7.4.3.kt
package com.a51work6.section4
fun main(args: Array) {
val string ="AB12CD34EF"
val regex =Regex("""\d+""")
val result =regex.find(string) ①
println("第1个匹配字符串:${result?.value}") ②
regex.findAll(string).forEach { e -> ③
println(e.value) ④
}
}
输出结果:
第1个匹配字符串:12
12
34
上述代码第①行在"AB12CD34EF"字符串中查找第一个匹配模式的字符串,本例是查找数字字符串。代码第②行value是MatchResult属性,可以获得找到的字符串。代码第③行findAll 函数可以找出全部的匹配字符串,forEach函数是遍历集合所有元素,forEach 后面的{ e ->… }表达式是Lambda表达式,Lambda表达式将在第14章介绍。代码④行中e是集合中元素变量,e.value是取出匹配字符串。
7.4.4 字符串替换
正则表达式还经常用于字符串替换。Regex中字符串替换相关函数如下:
replace(input: CharSequence,
replacement: String): String。input参数是输入字符串,replacement要替换的新字符串,返回值替换之后的字符串。
示例代码如下:
//代码文件:chapter7/src/com/a51work6/section4/ch7.4.4.kt
package com.a51work6.section4
fun main(args: Array) {
val string ="AB12CD34EF"
val regex =Regex("""\d+""")
val result =regex.replace(string, " ") ①
println(result)//AB CD EF ②
}
输出结果:
AB CD EF
代码第①行是将"AB12CD34EF"中的数字字符串替换为空格" "。
7.4.5 字符串分割
正则表达式还可以进行字符串分割。Regex中字符串分割相关函数如下:
split(input:CharSequence, limit: Int): List。input参数是输入字符串,limit是分割子字符串最大个数,如果为0表示没有限制,返回值是List字符串集合。
示例代码如下:
//代码文件:chapter7/src/com/a51work6/section4/ch7.4.5.kt
package com.a51work6.section4
fun main(args: Array) {
val string =“AB12CD34EF”
val regex =Regex("""\d+""")
val result =regex.split(string) ①
println(result)//[AB, CD, EF]
}
输出结果:
[AB, CD, EF]
代码第①行是使用数字字符串分割"AB12CD34EF"字符串,返回List集合,其中有三个元素。
本章介绍了Kotlin中的字符串,其中包括字符串字面量、不可变字符串和可变字符串,然后介绍不可变字符串中介绍了字符串拼接、字符串模板、字符串查找、字符串比较和字符串截取,接着介绍了可变字符串追加、插入、删除和替换。最后介绍正则表达式。