Question

J'apprends Scala, il est sans doute assez Noob-irific.

Je veux avoir une expression régulière multiligne.

Dans Ruby, il serait:

MY_REGEX = /com:Node/m

Mon Scala ressemble à:

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

Voici ma fonction de correspondance:

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

Et je vous appelle comme ceci:

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

J'ai essayé:

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

Et je voudrais vraiment éviter d'avoir à utiliser java.util.regex.Pattern. Des conseils très appréciés.

Était-ce utile?

La solution

Ceci est un problème très fréquent lors de la première utilisation de Scala Regex.

Lorsque vous utilisez pattern matching dans Scala, il tente de faire correspondre la chaîne entière, comme si vous utilisiez « ^ » et « $ » (et ne pas activer l'analyse de plusieurs lignes, ce qui correspond \ n à ^ et $) .

La façon de faire ce que vous voulez serait l'un des éléments suivants:

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

Qui trouverait trouver la première instance de scriptNode dans la valeur et retour que par exemple que v (si vous voulez que la chaîne entière, juste valeur d'impression). Ou bien:

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
  }

Ce qui imprimerait toute valeur tout. Dans cet exemple, (? S) active correspondant dotall (c.-à-correspondant « » aux nouvelles lignes), et le. * Avant et après le modèle cherchés assure qu'il ne importe quelle chaîne. Si vous vouliez « v » comme dans le premier exemple, vous pouvez faire ceci:

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
  }

Autres conseils

Juste un addendum rapide et sale: la méthode .r sur RichString convertit toutes les chaînes de scala.util.matching.Regex, de sorte que vous pouvez faire quelque chose comme ceci:

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

Et qui renverra

A
B
c

Je l'utilise tout le temps pour regex-script rapide et sale dans la console scala.

Ou dans ce cas:

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

Juste ma tentative de réduire l'utilisation du mot new dans le code dans le monde entier. ;)

Juste un petit plus, l'utilisation a essayé d'utiliser la (?m) (multiline) (bien qu'il pourrait ne pas convenir ici) mais voici la bonne façon de l'utiliser:

par exemple. au lieu de

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

utilisation

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

Mais encore une fois le (? S) drapeau est plus approprié dans cette question (l'ajout de cette réponse que parce que le titre est « Scala Regex activer l'option multiligne »)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top