Scala 正则表达式
本章介绍了Scala如何通过scala.util.matching包中的 Regex 类来支持正则表达式。
尝试以下示例程序,我们将尝试从一个语句中找出单词 Scala 。
示例
import scala.util.matching.Regex
object Demo {
def main(args: Array[String]) {
val pattern = "Scala".r
val str = "Scala is Scalable and cool"
println(pattern findFirstIn str)
}
}
将上述程序保存在 Demo.scala 中。以下命令用于编译和执行此程序。
命令
>scalac Demo.scala
\>scala Demo
输出
Some(Scala)
我们创建一个字符串并在其上调用r()方法。Scala会将字符串隐式转换为RichString,并调用该方法以获取一个Regex实例。要找到正则表达式的第一个匹配项,只需调用findFirstIn()方法。如果我们想找到匹配词的所有出现而不仅仅是第一个出现,可以使用findAllIn()方法。如果目标字符串中有多个Scala单词可用,这将返回所有匹配单词的集合。
您可以使用mkString()方法将结果列表连接起来,并可以使用pipe (|)来搜索Scala的小写和大写形式,您还可以使用Regex构造函数代替r()方法来创建一个模式。
请尝试以下示例程序。
示例
import scala.util.matching.Regex
object Demo {
def main(args: Array[String]) {
val pattern = new Regex("(S|s)cala")
val str = "Scala is scalable and cool"
println((pattern findAllIn str).mkString(","))
}
}
将上述程序保存在 Demo.scala 中。以下命令用于编译和执行此程序。
命令
>scalac Demo.scala
\>scala Demo
输出
Scala,scala
如果您想要替换匹配的文本,我们可以使用 replaceFirstIn() 来替换第一个匹配项, 或者使用 replaceAllIn() 来替换所有出现的匹配项。
示例
object Demo {
def main(args: Array[String]) {
val pattern = "(S|s)cala".r
val str = "Scala is scalable and cool"
println(pattern replaceFirstIn(str, "Java"))
}
}
将上面的程序保存在 Demo.scala 中。使用以下命令编译和执行该程序。
命令
>scalac Demo.scala
\>scala Demo
输出
Java is scalable and cool
形成正则表达式
Scala继承了Java的正则表达式语法,而Java又继承了Perl的大部分特性。以下只是一些示例,应该足够作为复习的参考。
下表列出了Java中所有可用的正则表达式元字符语法。
子表达式 | 匹配 |
---|---|
^ | 匹配行的开头。 |
$ | 匹配行的末尾。 |
. | 匹配除换行符外的任意单个字符。使用m选项可以使其匹配换行符。 |
[…] | 匹配方括号中的任意单个字符。 |
[^…] | 匹配不在方括号中的任意单个字符。 |
\\A | 整个字符串的开头。 |
\\z | 整个字符串的末尾。 |
\\Z | 整个字符串的结尾,但不包括可接受的最后一行终止符。 |
re* | 匹配零个或多个前面的表达式。 |
re+ | 匹配前一个元素的一个或多个实例 |
re? | 匹配前面的表达式的零个或一个实例。 |
re{ n} | 匹配前面的表达式的恰好n次实例。 |
re{ n,} | 匹配前面的表达式的n次或更多实例。 |
re{ n, m} | 匹配前面的表达式的至少n次和最多m次实例。 |
a | b | 匹配a或b。 |
(re) | 对正则表达式进行分组,并记住匹配的文本。 |
(?: re) | 分组正则表达式,不记住匹配的文本。 |
(?> re) | 匹配独立模式,无回溯。 |
\w | 匹配单词字符。 |
\W | 匹配非单词字符。 |
\s | 匹配空白字符。等同于 [\t\n\r\f]。 |
\S | 匹配非空白字符。 |
\d | 匹配数字。等同于 [0-9]。 |
\D | 匹配非数字。 |
\A | 匹配字符串的开头。 |
\Z | 匹配字符串的结尾。如果存在换行符,则匹配换行符前的位置。 |
\\z | 匹配字符串的末尾。 |
\\G | 匹配上一次匹配结束的地点。 |
\\n | 反向引用捕获组编号为“n”的结果。 |
\\b | 当位于括号外时,匹配单词边界。当位于括号内时,匹配退格符 (0x08)。 |
\\B | 匹配非单词边界。 |
\\n, \\t, 等等 | 匹配换行符、回车符、制表符等。 |
\\Q | 转义(引用)直到 \\E 的所有字符。 |
\\E | 结束由 \\Q 开始的引用。 |
正则表达式示例
示例 | 描述 |
---|---|
. | 匹配任意字符,除了换行符 |
[Rr]uby | 匹配 “Ruby” 或 “ruby” |
rub[ye] | 匹配 “ruby” 或 “rube” |
[aeiou] | 匹配任意一个小写元音字母 |
[0-9] | 匹配任意数字,等同于 [0123456789] |
[a-z] | 匹配任意一个小写ASCII字母 |
[A-Z] | 匹配任意一个大写ASCII字母 |
[a-zA-Z0-9] | 匹配上述任意字符 |
[^aeiou] | 匹配除了小写元音字母之外的任意字符 |
[^0-9] | 匹配除数字以外的任何字符 |
\\d | 匹配一个数字:[0-9] |
\\D | 匹配一个非数字字符:[^0-9] |
\\s | 匹配一个空白字符:[ \t\r\n\f] |
\\S | 匹配非空白字符:[^ \t\r\n\f] |
\\w | 匹配一个单词字符:[A-Za-z0-9_] |
\\W | 匹配一个非单词字符:[^A-Za-z0-9_] |
ruby? | 匹配”rub”或”ruby”:y是可选的 |
ruby* | 匹配”rub”加上0个或多个y |
ruby+ | 匹配”rub”加上1个或多个y |
\\d{3} | 完全匹配3个数字 |
\\d{3,} | 匹配3个或更多数字 |
\\d{3,5} | 匹配3个、4个或5个数字 |
\\D\\d+ | 无分组:+重复\\d |
(\\D\\d)+/ | 分组:+重复\\D\\d对 |
([Rr]uby(, )?)+ | 匹配”Ruby”、”Ruby, ruby, ruby”等 |
注意 − 在上面的字符串中,每个反斜杠都出现两次。这是因为在Java和Scala中,单个反斜杠是字符串字面值中的转义字符,不是字符串中显示的正常字符。所以,你需要写成‘\\’来得到一个字符串中的单个反斜杠,而不是‘\’。
试试以下示例程序。
示例
import scala.util.matching.Regex
object Demo {
def main(args: Array[String]) {
val pattern = new Regex("abl[ae]\\d+")
val str = "ablaw is able1 and cool"
println((pattern findAllIn str).mkString(","))
}
}
将上述程序保存在 Demo.scala 中。以下命令用于编译和执行该程序。
命令
>scalac Demo.scala
\>scala Demo
输出
able1