8

Ruby では、正規表現が 2 つある場合、次のように別の正規表現を作成できます。

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

Scalaで同じことをしたいのですが、どうすればそれができるかわかりませんでした。前の例のように、文字クラスの結合を作成するための構文を求めているわけではないことに注意してください(\d+)|(\s+)。与えられた 2 つの正規表現から新しい正規表現を作成する可能性を実際に探しています。

実際には、最終的には、2 つの正規表現だけではなく、多数の正規表現に対して行います。グループ化などは気にしません。文字列が特定の正規表現のリストのいずれかと一致するかどうかを知りたいだけです。それらすべてをループでチェックすることもできますが、それは非効率的です。そのため、ユニオンをチェックするために 1 つの Regexp が必要です。

4

4 に答える 4

9

Scala は、クラスに基づく Java 正規表現エンジンを使用しますjava.util.regex.PatternPattern正規表現を作成できるメソッドが 1 つだけあります。

public static Pattern compile(String regex)

それだけです。Scala は関連する拡張機能を提供しません。

しかし、できることの 1 つは、match ステートメントで組み込みの共用体を使用することです。ここでは、文字列から何かを取り出したい場合に備えて、グループをキャプチャすることを示しています。

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

scala> "45" match { case Dig(_) | Wsp(_) => println("found"); case _ => }

見つかった

scala> "   " match { case Dig(_) | Wsp(_) => println("found"); case _ => }

見つかった

組み合わせた正規表現が本当に必要な場合は、文字列レベルで行う必要があります。Patternを使用して Scala 正規表現からJava を取得し.pattern、別の方法.patternで文字列を取得できます。(?:)ほとんどの正規表現は、非キャプチャ ブロックを取得するために安全にラップできるため、次のように組み合わせることができます。

val Both = ("(?:"+Dig.pattern.pattern+")|(?:"+Wsp.pattern.pattern+")").r

ただし、内部のキャプチャ グループは両方とも表されますが、使用されていないブランチは次のようになります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
于 2012-12-11T16:11:57.053 に答える
1

正規表現の部分を組み合わせて再利用したい場合は、それを行うライブラリ/DSL であるRELを作成しました。あなたの場合の使用例:

import fr.splayce.rel._
import Implicits._

val a: RE = "\\d+"
val b: RE = "\\s+"
val c: RE = a | b

crRegex オブジェクトを取得するメソッドがあります。にもあるImplicitsので、正規表現として使用できますc findAllIn someText。必要に応じて、自動的にラップabれ、非キャプチャ グループになります。

正規表現のコレクションがある場合は、次のようにするだけですreduceLeft

val regexes: List[RE] = List("a", "b", "c")
regexes.reduceLeft(_ | _)

余談ですが:

  • をインポートすると、やSymbols._などの短い表記があります。\d\s
  • 再利用性を最大限に高めるために、通常の正規表現操作のほとんどを実装します

したがって、REL を使用すると、最初の例を次のように直接記述できます。

val c = δ.+ | σ.+

また、関連するエクストラクタを再利用および結合する方法も提供します。

バニラのスカラがお好みなら、Rex Kerr の回答に追加するものは何もありません。

于 2012-12-11T17:33:27.637 に答える