Scala Regex联盟

Lyk*_*kos 7 regex scala

在Ruby中,如果我有两个Regexp,我有可能创建另一个这样的正则表达式:

a = /\d+/ # Matches digits
b = /\s+/ # Matches whitespaces
c = Regexp.union(a, b) # Matches sequences that consist only of digits or only of whitespaces
Run Code Online (Sandbox Code Playgroud)

我想在Scala中做同样的事情,但我没有发现我怎么能做到这一点.请注意,我不是要求语法来创建像(\d+)|(\s+)前面示例中那样的字符类联合,我真的在寻找从两个给定的Regexp创建新Regexp的可能性.

实际上,最后,我不会只为两个正则表达式而是大量表示.我不关心分组或任何东西,我只想知道一个String是否与给定的Regexp列表中的一个匹配.我可以在循环中检查所有这些,但这样效率太低,这就是为什么我需要一个Regexp来检查联合.

Rex*_*err 7

Scala使用基于类的Java正则表达式引擎java.util.regex.Pattern. Pattern有一个方法可以创建一个正则表达式:

public static Pattern compile(String regex)
Run Code Online (Sandbox Code Playgroud)

就是这样,Scala没有给你任何相关的增强功能.

但是你可以做的一件事就是在匹配语句中使用内置联合,这里显示捕获组,以防你想从字符串中取出一些内容:

val Dig = """(\d+)""".r
val Wsp = """(\s+)""".r

scala> "45" match { case Dig(_) | Wsp(_) => println("found"); case _ => }
Run Code Online (Sandbox Code Playgroud)

发现

scala> "   " match { case Dig(_) | Wsp(_) => println("found"); case _ => }
Run Code Online (Sandbox Code Playgroud)

发现

如果你真的想要一个组合的正则表达式,你必须在字符串级别进行.你可以Pattern从Scala正则表达式获取java .pattern,然后另一个.pattern获取字符串.大多数正则表达式可以安全地包装(?:)以获得非捕获块,因此您可以像这样组合:

val Both = ("(?:"+Dig.pattern.pattern+")|(?:"+Wsp.pattern.pattern+")").r
Run Code Online (Sandbox Code Playgroud)

但是,内部的任何捕获组将被表示,但未使用的分支将是null(不完全是编写惯用的Scala的好方法,但无论如何,这是Java使用的):

scala> "2" match { case Both(d,w) => if (w!=null) println("white") else println(d) }
2

scala> " " match { case Both(d,w) => if (w!=null) println("white") else println(d) }
white
Run Code Online (Sandbox Code Playgroud)

  • @Lykos - 您总是可以编写一个将对或序列放在一起的方法.例如,如果`xs`是正则表达式的集合,`xs.map(_.pattern.pattern).mkString("(?:",")|(?:",")").r`应该是一大堆他们在一起的正则表达式 (2认同)