Scala Regex启用Multiline选项

时间:2009-07-06 18:32:50

标签: regex scala multiline

我正在学习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。任何提示都非常感激。

3 个答案:

答案 0 :(得分:40)

首次使用Scala Regex时,这是一个非常常见的问题。

当你在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)激活dotall匹配(即匹配“。”到新行),而搜索模式之前和之后的。*确保它匹配任何字符串。如果你想要第一个例子中的“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
  }

答案 1 :(得分: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一词的使用。 ;)

答案 2 :(得分:5)

只是一个小小的添加,使用尝试使用(?m)(多行)标志(虽然它可能不适合这里),但这是使用它的正确方法:

e.g。而不是

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

使用

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

但是(?s)标志更适合这个问题(仅因为标题为“Scala Regex启用多行选项”而添加此答案)