2009-07-06 67 views
20

我正在学习Scala,所以这可能是相当noob-irific。斯卡拉正则表达式启用多行选项

我想要一个多行正则表达式。

在Ruby中这将是:

MY_REGEX = /com:Node/m 

我的斯卡拉看起来像:

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中。任何提示不胜感激。

+0

格式化的欢呼声!没有为我工作 – 2009-07-06 18:44:11

+1

你必须在每个代码块的上面和下面留一个空行。 – 2009-07-06 19:24:10

回答

36

这是第一次使用Scala Regex时的一个非常常见的问题。当您在Scala中使用模式匹配时,它会尝试匹配整个字符串,就好像您使用的是“^”和“$”(并且没有激活多行解析,匹配\和$以及$ )。

做你想做的将是以下中的一个什么样的方式:

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 
    } 
5

只是快速和肮脏的增编:RichString.r方法的所有字符串转换为scala.util.matching.Regex,所以你可以做这样的事情:

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

这将返回

A 
B 
c 

我用这一切都为快速和肮脏的正则表达式脚本的时间在斯卡拉CON唯一。

或在这种情况下:

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的。;)

3

只是一个小此外,利用试图用(?m)(多行)标志(虽然它可能不适合在这里),但这里是用正确的方式:

例如而不是

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

使用

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

但同样的(?S)的标志,更适合在这个问题上(只增加是因为标题是“Scala的正则表达式启用多行选项”这个答案)