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
极客教程