21

私はScalaを学んでいるので、これはおそらくかなり初心者です。

複数行の正規表現が欲しいのですが。

Rubyでは次のようになります。

MY_REGEX = /com:Node/m

私のScalaは次のようになります:

val ScriptNode =  new Regex("""<com:Node>""")

これが私の一致関数です:

def matchNode( value : String ) : Boolean = value match 
{
    case ScriptNode() => System.out.println( "found" + value ); true
    case _ => System.out.println("not found: " + value ) ; false
}

そして、私はそれをそのように呼んでいます:

matchNode( "<root>\n<com:Node>\n</root>" ) // doesn't work
matchNode( "<com:Node>" ) // works

私はもう試した:

val ScriptNode =  new Regex("""<com:Node>?m""")

そして、java.util.regex.Patternを使用する必要を本当に避けたいと思います。ヒントは大歓迎です。

4

3 に答える 3

44

これは、ScalaRegexを最初に使用するときに非常に一般的な問題です。

Scalaでパターンマッチングを使用すると、「^」と「$」を使用しているかのように文字列全体を一致させようとします(\ nを^と$に一致させる複数行の解析をアクティブにしませんでした)。

あなたが望むことをする方法は次のいずれかです:

def matchNode( value : String ) : Boolean = 
  (ScriptNode findFirstIn value) match {    
    case Some(v) => println( "found" + v ); true    
    case None => println("not found: " + value ) ; false
  }

これにより、値内でScriptNodeの最初のインスタンスが検出され、そのインスタンスがvとして返されます(文字列全体が必要な場合は、値を出力するだけです)。または:

val ScriptNode =  new Regex("""(?s).*<com:Node>.*""")
def matchNode( value : String ) : Boolean = 
  value match {    
    case ScriptNode() => println( "found" + value ); true    
    case _ => println("not found: " + value ) ; false
  }

これはすべての値を出力します。この例では、(?s)はドットオールマッチング(つまり、「。」を新しい行にマッチングする)をアクティブにし、検索されたパターンの前後の。*は、任意の文字列に一致することを保証します。最初の例のように「v」が必要な場合は、次のように実行できます。

val ScriptNode =  new Regex("""(?s).*(<com:Node>).*""")
def matchNode( value : String ) : Boolean = 
  value match {    
    case ScriptNode(v) => println( "found" + v ); true    
    case _ => println("not found: " + value ) ; false
  }
于 2009-07-06T20:41:51.777 に答える
5

簡単で汚い補遺:の.rメソッドはRichStringすべての文字列をに変換するscala.util.matching.Regexので、次のようなことができます。

"""(?s)a.*b""".r replaceAllIn ( "a\nb\nc\n", "A\nB" )

そしてそれは戻ります

A
B
c

私はいつもこれを使って、scalaコンソールでの迅速で汚い正規表現のスクリプティングを行っています。

またはこの場合:

def matchNode( value : String ) : Boolean = {

    """(?s).*(<com:Node>).*""".r.findAllIn( text ) match {

       case ScriptNode(v) => System.out.println( "found" + v ); true    

       case _ => System.out.println("not found: " + value ) ; false
    }
}

new世界中のコードでの単語の使用を減らすための私の試みです。;)

于 2009-07-10T07:37:10.330 に答える
5

ほんの少しの追加で、(Multiline)フラグを使用しようとしましたが(?m)(ここでは適切でない場合があります)、これが正しい使用方法です。

例:代わりに

val ScriptNode =  new Regex("""<com:Node>?m""")

使用する

val ScriptNode =  new Regex("""(?m)<com:Node>""")

ただし、この質問では(?s)フラグの方が適しています(タイトルが「Scala正規表現で複数行を有効にするオプション」であるという理由だけでこの回答を追加します)

于 2013-12-31T00:19:12.960 に答える