Scala Regex enable Multiline option

后端 未结 3 1098
滥情空心
滥情空心 2020-12-08 11:05

I\'m learning Scala, so this is probably pretty noob-irific.

I want to have a multiline regular expression.

In Ruby it would be:

MY_REGEX = /         


        
相关标签:
3条回答
  • 2020-12-08 11:40

    Just a small addition, use tried to use the (?m) (Multiline) flag (although it might not be suitable here) but here is the right way to use it:

    e.g. instead of

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

    use

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

    But again the (?s) flag is more suitable in this question (adding this answer only because the title is "Scala Regex enable Multiline option")

    0 讨论(0)
  • 2020-12-08 11:41

    This is a very common problem when first using Scala Regex.

    When you use pattern matching in Scala, it tries to match the whole string, as if you were using "^" and "$" (and did not activate multi-line parsing, which matches \n to ^ and $).

    The way to do what you want would be one of the following:

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

    Which would find find the first instance of ScriptNode inside value, and return that instance as v (if you want the whole string, just print value). Or else:

    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
      }
    

    Which would print all all value. In this example, (?s) activates dotall matching (ie, matching "." to new lines), and the .* before and after the searched-for pattern ensures it will match any string. If you wanted "v" as in the first example, you could do this:

    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
      }
    
    0 讨论(0)
  • 2020-12-08 11:43

    Just a quick and dirty addendum: the .r method on RichString converts all strings to scala.util.matching.Regex, so you can do something like this:

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

    And that will return

    A
    B
    c
    

    I use this all the time for quick and dirty regex-scripting in the scala console.

    Or in this case:

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

    Just my attempt to reduce the use of the word new in code worldwide. ;)

    0 讨论(0)
提交回复
热议问题