正则表达式( Regular Expressions)
本章介绍Scala如何通过scala.util.matching包中提供的Regex类支持正则表达式。
尝试以下示例程序,我们将尝试从语句中找出Scala一词。
例子 (Example)
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 。 以下命令用于编译和执行此程序。
Command
\>scalac Demo.scala
\>scala Demo
输出 (Output)
Some(Scala)
我们创建一个String并在其上调用r( )方法。 Scala隐式地将String转换为RichString并调用该方法来获取Regex的实例。 要查找正则表达式的第一个匹配项,只需调用findFirstIn()方法即可。 如果我们不想仅查找第一次出现的匹配单词,我们可以使用findAllIn( )方法,如果目标字符串中有多个Scala单词,则会返回所有匹配的集合话。
您可以使用mkString()方法来连接结果列表,您可以使用管道(|)来搜索Scala的小型和大写情况,您可以使用Regex构造函数或r()方法来创建模式。
请尝试以下示例程序。
例子 (Example)
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 。 以下命令用于编译和执行此程序。
Command
\>scalac Demo.scala
\>scala Demo
输出 (Output)
Scala,scala
如果您想替换匹配的文本,我们可以使用replaceFirstIn( )替换第一个匹配或replaceAllIn( )来替换所有匹配项。
例子 (Example)
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 。 以下命令用于编译和执行此程序。
Command
\>scalac Demo.scala
\>scala Demo
输出 (Output)
Java is scalable and cool
形成正则表达式
Scala从Java继承了它的正则表达式语法,后者又继承了Perl的大部分功能。 这里只是一些应该足够复兴的例子 -
以下是列出Java中可用的所有正则表达式Meta字符语法的表。
子表达式 | 火柴 |
---|---|
^ | 匹配行首。 |
$ | 匹配行尾。 |
. | 匹配除换行符之外的任何单个字符。 使用m选项也可以匹配换行符。 |
[...] | 匹配括号中的任何单个字符。 |
[^...] | 匹配不在括号中的任何单个字符 |
\\A | 整个字符串的开头 |
\\z | 整个字符串的结尾 |
\\Z | 除允许的最终行终止符之外的整个字符串的结尾。 |
re* | 匹配前面表达式的0次或更多次出现。 |
re+ | 匹配前一项中的一项或多项 |
re? | 匹配前面表达式的0或1次出现。 |
re{ n} | 准确匹配前面表达式的n个出现次数。 |
re {n,} | 匹配前面表达式的n次或多次出现。 |
re {n,m} | 匹配前面表达式的至少n次和最多m次出现。 |
a|b | 匹配a或b。 |
(re) | 对正则表达式进行分组并记住匹配的文本。 |
(?: 回覆) | 将正则表达式分组而不记住匹配的文本。 |
(?> re) | 匹配独立模式,无需回溯。 |
\\w | 匹配单词字符。 |
\\W | 匹配非单词字符。 |
\\s | 匹配空白。 相当于[\ t\n\r\n]。 |
\\S | 匹配非空白。 |
\\d | 匹配数字。 相当于[0-9]。 |
\\D | 匹配非数字。 |
\\A | 匹配字符串的开头。 |
\\Z | 匹配字符串的结尾。 如果存在换行符,则它在换行符之前匹配。 |
\\z | 匹配字符串的结尾。 |
\\G | 匹配指向上一场比赛结束的位置。 |
\\n | 反向捕获组号“n” |
\\b | 在括号外匹配单词边界。 在括号内匹配退格(0x08)。 |
\\B | 匹配非字边界。 |
\\n, \\t, etc. | 匹配换行符,回车符,制表符等。 |
\\Q | 逃脱(引用)所有字符到\\ E |
\\E | 结束引用以\\ Q开头 |
正则表达式示例
例 | 描述 |
---|---|
. | 匹配除换行符之外的任何字符 |
[Rr]uby | 匹配“Ruby”或“ruby” |
rub[ye] | 匹配“红宝石”或“鲁布” |
[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或更多ys |
ruby+ | 匹配“擦”加1或更多ys |
\\d{3} | Match exactly 3 digits |
\\d{3,} | 匹配3位或更多位数 |
\\d{3,5} | 匹配3,4或5位数 |
\\D\\d+ | 没有组:+重复\\ d |
(\\D\\d)+/ | 分组:+重复\\ D\d对 |
([Rr]uby(, )?)+ | 匹配“Ruby”,“Ruby,ruby,ruby”等。 |
Note - 每个反斜杠在上面的字符串中出现两次。 这是因为在Java和Scala中,单个反斜杠是字符串文字中的转义字符,而不是字符串中显示的常规字符。 因此,不需要'\',而是需要编写'\\'以在字符串中获得单个反斜杠。
请尝试以下示例程序。
例子 (Example)
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 。 以下命令用于编译和执行此程序。
Command
\>scalac Demo.scala
\>scala Demo
输出 (Output)
able1