2009-07-06 65 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的正則表達式啓用多行選項」這個答案)