J'aimerais pouvoir trouver une correspondance entre la première lettre d'un mot et l'une des lettres d'un groupe tel que "ABC". En pseudocode, cela pourrait ressembler à quelque chose comme:
case Process(word) =>
word.firstLetter match {
case([a-c][A-C]) =>
case _ =>
}
}
Mais comment récupérer la première lettre dans Scala au lieu de Java? Comment exprimer correctement l'expression régulière? Est-il possible de faire cela dans une classe de cas ?
[a-cA-C]
cette expression régulière.Traversable
(commeList
etArray
), si vous voulez les 3 premiers caractères, essayez"my string".take(3)
, pour le premier"foo".head
Réponses:
Vous pouvez le faire car les expressions régulières définissent des extracteurs, mais vous devez d'abord définir le modèle d'expression régulière. Je n'ai pas accès à un REPL Scala pour tester cela mais quelque chose comme ça devrait fonctionner.
la source
val Pattern = "[a-cA-C]".r
ne fonctionnera pas. En effet, la casse de correspondance utiliseunapplySeq(target: Any): Option[List[String]]
, qui renvoie les groupes correspondants.val r = "[A-Ca-c]".r ; 'a' match { case r() => }
.. scala-lang.org/api/current/#scala.util.matching.Regexval r = "([A-Ca-c])".r ; "C" match { case r(_*) => }
.Depuis la version 2.10, on peut utiliser la fonction d'interpolation de chaîne de Scala:
Mieux encore, on peut lier des groupes d'expressions régulières:
Il est également possible de définir des mécanismes de liaison plus détaillés:
Un exemple impressionnant de ce qui est possible avec
Dynamic
est montré dans l'article de blog Introduction to Type Dynamic :la source
$
signe comme motif de fin de ligne: le compilateur se plaint du manque de terminaison de chaîne.case p.firstName.lastName.Map(...
modèle - comment diable puis -je lire cela?Regex
chaque fois que la correspondance est vérifiée. Et c'est une opération assez coûteuse qui implique la compilation du modèle regex.Comme l'a souligné delnan, le
match
mot - clé dans Scala n'a rien à voir avec les expressions régulières. Pour savoir si une chaîne correspond à une expression régulière, vous pouvez utiliser laString.matches
méthode. Pour savoir si une chaîne commence par un a, b ou c en minuscule ou en majuscule, l'expression régulière ressemblerait à ceci:Vous pouvez lire cette expression régulière comme "l'un des caractères a, b, c, A, B ou C suivi de n'importe quoi" (
.
signifie "n'importe quel caractère" et*
signifie "zéro fois ou plus", donc ". *" Est une chaîne) .la source
Pour développer un peu la réponse d'Andrew : Le fait que les expressions régulières définissent des extracteurs peut être utilisé pour décomposer très bien les sous-chaînes correspondant à l'expression régulière en utilisant la correspondance de motifs de Scala, par exemple:
la source
[]
), le signe curseur indique la négation, donc[^\s]
signifie «sans espace».String.matches est le moyen de faire la correspondance de motifs dans le sens de l'expression régulière.
Mais en passant, word.firstLetter en vrai code Scala ressemble à:
Scala traite les chaînes comme une séquence de caractères, donc si pour une raison quelconque vous vouliez explicitement obtenir le premier caractère de la chaîne et le faire correspondre, vous pouvez utiliser quelque chose comme ceci:
Je ne propose pas cela comme moyen général de faire la correspondance de motifs regex, mais cela correspond à votre approche proposée pour trouver d'abord le premier caractère d'une chaîne, puis le faire correspondre à une expression régulière.
EDIT: Pour être clair, la façon dont je ferais cela est, comme d'autres l'ont dit:
Je voulais juste montrer un exemple aussi proche que possible de votre pseudo-code initial. À votre santé!
la source
"Cat"(0).toString
pourrait être plus clairement écrit comme"Cat" take 1
, à mon humble avis.val r = "[A-Ca-c]".r ; "cat"(0) match { case r() => }
.Notez que l'approche de la réponse de @ AndrewMyers fait correspondre la chaîne entière à l'expression régulière, avec pour effet d'ancrer l'expression régulière aux deux extrémités de la chaîne en utilisant
^
et$
. Exemple:Et sans
.*
à la fin:la source
val MY_RE2 = "(foo|bar)".r.unanchored ; "foo123" match { case MY_RE2(_*) => }
. Plus idiomatiquement,val re
sans toutes les majuscules.Tout d'abord, nous devons savoir que l'expression régulière peut être utilisée séparément. Voici un exemple:
Deuxièmement, nous devrions remarquer que combiner une expression régulière avec une correspondance de modèle serait très puissant. Voici un exemple simple.
En fait, l'expression régulière elle-même est déjà très puissante; la seule chose que nous devons faire est de le rendre plus puissant par Scala. Voici d'autres exemples dans le document Scala: http://www.scala-lang.org/files/archive/api/current/index.html#scala.util.matching.Regex
la source