Scala 字符串
最后修改于 2023 年 1 月 10 日
在本文中,我们将介绍如何在 Scala 中处理字符串。
Scala 字符串定义
在 Scala 中,String 是 Unicode 字符序列。字符串是对象。有两种基本的字符串处理类型:
String
StringBuilder
String
是一个不可变的 Unicode 字符序列。StringBuilder
是一个可变的 Unicode 字符序列。
字符串字面量是源代码中用双引号括起来的一系列字符。例如,“falcon”就是一个字符串字面量。
Scala 字符串简单示例
第一个示例是一个简单的 Scala 字符串示例。
@main def main() = val w = "an old falcon" println(w) val msg = "an " + "old " + "falcon" println(msg)
我们定义了两个字符串。
val w = "an old falcon" println(w)
字符串字面量绑定到 w
标识符。字符串字面量用双引号括起来。它使用 println
打印到控制台。
val msg = "an " + "old " + "falcon"
我们使用 +
运算符将三个字符串连接成一条消息。
$ scala main.scala an old falcon an old falcon
Scala 可变和不可变字符串
String
是一个不可变的 Unicode 字符序列,而 StringBuilder
是一个可变的 Unicode 字符序列。下一个示例将展示区别。
import scala.collection.mutable.StringBuilder @main def main() = val name = "Jane" val name2 = name.replace('J', 'K') val name3 = name2.replace('n', 't') println(name) println(name3) val sb = StringBuilder("Jane") println(sb) sb.setCharAt(0, 'K') sb.setCharAt(2, 't') println(sb)
这两个对象都有替换字符串中字符的方法。
val name = "Jane" val name2 = name.replace('J', 'K') val name3 = name2.replace('n', 't')
在 String
上调用 replace
方法会返回一个新的修改后的字符串。原始字符串不会被更改。
sb.setCharAt(0, 'K') sb.setCharAt(2, 't')
StringBuilder
的 setCharAt
方法将用新字符替换给定索引处的字符。原始字符串会被修改。
$ scala main.scala Jane Kate Jane Kate
Scala 多行字符串
可以使用三引号创建多行字符串。为了删除前导空格,我们使用 |
字符和 stripMargin
方法。
@main def main() = val sonnet55 = """Not marble nor the gilded monuments |Of princes shall outlive this powerful rhyme, |But you shall shine more bright in these contents |Than unswept stone besmeared with sluttish time. |When wasteful war shall statues overturn, |And broils root out the work of masonry, |Nor Mars his sword nor war's quick fire shall burn |The living record of your memory. |'Gainst death and all-oblivious enmity |Shall you pace forth; your praise shall still find room |Even in the eyes of all posterity |That wear this world out to the ending doom. |So, till the Judgement that yourself arise, |You live in this, and dwell in lovers' eyes.""".stripMargin println(sonnet55)
我们在多行字符串中有一个诗句。
$ scala main.scala Not marble nor the gilded monuments Of princes shall outlive this powerful rhyme, But you shall shine more bright in these contents ...
Scala 字符串转义字符
转义字符是执行特定操作的特殊字符。例如,\n
字符会开始新的一行。
@main def main() = println("Three\t bottles of wine") println("He said: \"I love ice skating\"") println("Line 1:\nLine 2:\nLine 3:")
我们有一个包含转义字符的示例。
println("Three\t bottles of wine")
\t
转义字符插入一个制表符。
println("He said: \"I love ice skating\"")
我们通过转义它们来在字符串字面量中插入双引号,使用 \
。
println("Line 1:\nLine 2:\nLine 3:")
使用 \n
,我们创建了三行。
$ scala main.scala Three bottles of wine He said: "I love ice skating" Line 1: Line 2: Line 3:
Scala 原生字符串
在原生字符串中,转义字符不会被解释。
@main def main() = println(raw"snow\tshow\tsnow") println("becomes") println("snow\tshow\tsnow")
示例使用了一个原生字符串。
$ scala main.scala snow\tshow\tsnow becomes snow show snow
Scala 比较字符串
字符串自然地使用 ==
和 !=
运算符进行比较。
@main def main() = val s1 = "Eagle" val s2 = "eagle" if s1 != s2 then println("1) strings are not equal") if s1 == s2.capitalize then println("2) strings are equal")
在示例中,我们比较了两个字符串。
$ scala main.scala 1) strings are not equal 2) strings are equal
Scala 索引字符串字符
我们可以通过索引检索字符串字符。索引从零开始。
@main def main() = val w = "and old falcon" println(w(0)) println(w(5))
在示例中,我们打印了第一个和第六个字符。
Scala 分割字符串
split
函数根据指定的分隔符将字符串分割成字符串列表。
@main def main() = val word = "eagle,falcon,hawk,owl" val birds = word.split(",") birds.foreach(println)
我们有一个由逗号分隔的鸟类组成的字符串。我们将字符串分割以单独获取所有鸟类。
$ scala main.scala eagle falcon hawk owl
Scala 字符串 startsWith/endsWith
startsWith
方法如果字符串以指定的前缀开头,则返回 true,endsWith
方法如果字符串以指定的字符结尾,则返回 true。
@main def main() = val words = List("tank", "boy", "tourist", "ten", "pen", "car", "marble", "sonnet", "pleasant", "ink", "atom") val res = words.filter(e => startWithT(e)) println(res) val res2 = words.filter(e => endWithK(e)) println(res2) val startWithT = (word: String) => word.startsWith("t") val endWithK = (word: String) => word.endsWith("k")
我们有一系列单词。我们找出哪些单词以“t”开头,以“k”结尾。
val words = List("tank", "boy", "tourist", "ten", "pen", "car", "marble", "sonnet", "pleasant", "ink", "atom")
我们有一系列单词。
val res = words.filter(e => startWithT(e)) println(res) val res2 = words.filter(e => endWithK(e)) println(res2)
filter 函数会对它们的元素调用一个谓词。
val startWithT = (word: String) => word.startsWith("t")
startWithT
是一个自定义谓词函数,如果字符串以“t”开头,则返回 true。
$ scala main.scala List(tank, tourist, ten) List(tank, ink)
Scala 字符串插值
字符串插值是在字符串内用其值进行变量替换。插值字符串以 s
或 f
前缀开头。
@main def main() = val name = "Peter" val age = 34 println(s"$name is $age years old") val word = "falcon" println(s"The string has ${word.length} characters") val item = "beer" val price = 4.5 println(s"The price of $item is $$$price")
在示例中,我们使用 s
前缀对字符串进行插值。
val name = "Peter" val age = 34 println(s"$name is $age years old")
$name
和 $age
变量被替换为其值。
println(s"The string has ${word.length} characters")
使用 {}
大括号,我们可以在字符串内使用表达式。
println(s"The price of $item is $$$price")
为了使用美元符号,我们使用 $$
。
$ scala main.scala Peter is 34 years old The string has 6 characters The price of beer is $4.5
使用 f
前缀,我们还在变量名后提供格式化字符。
@main def main() = val name = "Peter" val age = 34 println(f"$name%s is $age%d years old")
我们使用 f 插值字符串构建一个字符串。
Scala 字符串转整数
我们使用 toInt
将字符串转换为整数。
@main def main() = val vals = List[String | Int]("3", 12, "11", 5, 6, "8") val vals2 = vals.map(_.toString.toInt) println(vals2.sum) var msum = 0 for e <- vals do msum = msum + e.toString.toInt println(msum)
我们有一个整数和字符串的列表。我们计算所有值的总和。
val vals2 = vals.map(_.toString.toInt) println(vals2.sum)
在求和之前,我们需要使用 map
和 toInt
将元素转换为整数。我们使用内置的 sum
函数来计算总和。
var msum = 0 for e <- vals do msum = msum + e.toString.toInt println(msum)
或者,我们使用 for 循环。
$ scala main.scala 45 45
Scala 字符串长度
对于许多字母,length
函数会给出正确的字符数。
@main def main() = val word = "falcon" println(word.length) val word2 = "čerešňa" println(word2.length) val word3 = "ведомство" println(word3.length) val word4 = "合気道" println(word4.length)
在示例中,我们打印了英语、斯洛伐克语、俄语和日语单词的字符数。
$ scala main.scala 6 7 9 3
结果是正确的。
有些字母的 length
会给出错误的结果。
import java.text.BreakIterator @main def main() = val emojis = "🐜🐬🐄🐘🦂🐫🐑🦍🐯🐞" println(emojis.length) val it = BreakIterator.getCharacterInstance it.setText(emojis) var count = 0 while it.next != BreakIterator.DONE do count += 1 println(count) println("--------------------------") val word = "नमस्ते" println(word.length) val it2 = BreakIterator.getCharacterInstance it2.setText(word) var count2 = 0 while it2.next != BreakIterator.DONE do count2 += 1 println(count2)
例如,对于表情符号和梵语单词,length
函数会给出错误的数字。我们可以使用 BreakIterator
获取表情符号的正确答案。然而,对于梵语单词,BreakIterator
仍然不正确。
$ scala main.scala 20 10 -------------------------- 6 3
正确答案是 10 个表情符号字符和 4 个梵语字符。
Scala 字符串行
lines
方法返回一个流,其中包含从字符串中提取的行,由行终止符分隔。
@main def main() = val words = """ |club |sky |blue |cup |coin |new |cent |owl |falcon |brave |war |ice |paint |water""".stripMargin val wstream = words.lines() wstream.forEach(word => if word.length() == 3 then println(word) )
我们在这段文本中有十四个单词。
var wstream = words.lines()
使用 lines
方法,我们创建了这个单词的流。
wstream.forEach(word => if word.length() == 3 then println(word) )
我们使用 forEach
遍历流,并打印所有长度为三个字母的单词。
$ scala main.scala sky cup new owl war ice
Scala 添加字符串
有几种方法可以添加或构建字符串。
@main def main() = val w1 = "an" val w2 = "old" val w3 = "falcon" val msg = w1 + " " + w2 + " " + w3 println(msg) println(w1.concat(" ").concat(w2).concat(" ").concat(w3)) println(s"$w1 $w2 $w3") println(f"$w1%s $w2%s $w3%s") printf("%s %s %s%n", w1, w2, w3)
在示例中,我们使用 +
运算符、concat
函数、字符串插值和 printf
函数构建字符串。
Scala 字符串匹配
matches
函数用于判断字符串是否与给定的正则表达式匹配。
@main def main() = var words = """ |book |bookshelf |bookworm |bookcase |bookish |bookkeeper |booklet |bookmark """.stripMargin var wstream = words.lines wstream.forEach(word => if word.matches("book(worm|mark|keeper)?") then println(word) )
在示例中,我们打印了所有满足指定子模式的单词。
$ scala main.scala book bookworm bookkeeper bookmark
Scala 字符串字节
我们可以使用 getBytes
获取底层字节。
@main def main() = val w = "and old falcon" println(w.getBytes.mkString(" ")) println(w.getBytes.map("%02x ".format(_)).mkString)
该示例以十进制和十六进制格式打印字符串的字节值。
println(w.getBytes.mkString(" "))
getBytes
返回一个字节数组。我们使用 mkString
将它们连接成一个字符串;值之间用空格分隔。
$ scala main.scala 97 110 100 32 111 108 100 32 102 97 108 99 111 110 61 6e 64 20 6f 6c 64 20 66 61 6c 63 6f 6e
Scala 连接字符串
我们可以使用 mkString
连接字符串列表。
@main def main() = val words = List("work", "sky", "place", "cup") val joined = words.mkString(" ") println(joined) val joined2 = words.mkString(", ") println(joined2)
在示例中,我们将一个字符串列表连接成一个字符串。
val joined = words.mkString(" ")
mkString
方法的参数是一个分隔符,它将分隔最终字符串中的每个字符串。
$ scala main.scala work sky place cup work, sky, place, cup
在本文中,我们介绍了如何在 Scala 中处理字符串。