在Scala中可以用"""
的方式创建多行字符串,eg.
object StringTest {
def main(args: Array[String]): Unit = {
val s1 ="""This is
my first time
to learn Scala"""
println(s1)
}
}
输出如下:
This is
my first time
to learn Scala
但是这种方式有个问题,就是每行的开头可能会有空格;如何消除空格,可以在多行字符串的结尾添加stripMargin
方法,并且在第二行开始的每一行前面添加|
,eg.
object StringTest {
def main(args: Array[String]): Unit = {
val s1 ="""This is
|my first time
|to learn Scala""".stripMargin
println(s1)
}
}
输出如下:
This is
my first time
to learn Scala
如果不想使用|
,也可以使用其他任意字符,eg.
object StringTest {
def main(args: Array[String]): Unit = {
val s2 ="""This is
#my first time
#to learn Scala""".stripMargin('#')
println(s2)
}
}
输出如下:
This is
my first time
to learn Scala
此处需要注意,只能使用stripMargin('#'),而不能使用stripMargin("#"),这个会出现Cannot resolve reference stripMargin with such signature
;
Scala的多行,其实在每个换行的字符串之间生成\n
的换行符,可以将替换掉,eg.
val s3 ="""This is
#my first time
#to learn Scala""".stripMargin('#').replaceAll("\r\n", " ")
println(s3)
输出如下:
This is my first time to learn Scala
这个replace需要注意的是,在编辑器中需要使用replaceAll("\r\n", " ")
,但是在scala的REPL
中只需要使用replaceAll("\n", " ")
;原因如下:
Your Idea making the newline marker the standard Windows \r\n, so you've got "abcd\r\nefg". The regex is turning it into "abcd\refg" and Idea console is treaing the \r slightly differently from how the windows shell does. The REPL is just using \n as the new line marker so it works as expected.
Solution 1: change Idea to just use \n newlines.
Solution 2: don't use triple quoted strings when you need to control newlines, use single quotes and explicit \n characters.
Solution 3: use a more sophisticated regex to replace \r\n, \n, or \r
Scala多行字符串的另外一个功能是,单引号和双引号无需进行转义,eg.
val s4 ="""This is
#'my' first time
#to "learn" Scala""".stripMargin('#').replaceAll("\r\n", " ")
println(s4)
输出如下:
This is 'my' first time to "learn" Scala
stripMargin
函数在StringLike.scala
源码中默认使用了|
这个字符串;
/** For every line in this string:
*
* Strip a leading prefix consisting of blanks or control characters
* followed by `|` from the line.
*/
def stripMargin: String = stripMargin('|')
/** For every line in this string:
*
* Strip a leading prefix consisting of blanks or control characters
* followed by `marginChar` from the line.
*/
def stripMargin(marginChar: Char): String = {
val buf = new StringBuilder
for (line <- linesWithSeparators) {
val len = line.length
var index = 0
while (index < len && line.charAt(index) <= ' ') index += 1
buf append
(if (index < len && line.charAt(index) == marginChar) line.substring(index + 1) else line)
}
buf.toString
}