Ich möchte in der Lage sein, eine Übereinstimmung zwischen dem ersten Buchstaben eines Wortes und einem der Buchstaben in einer Gruppe wie "ABC" zu finden. Im Pseudocode könnte dies ungefähr so aussehen:
case Process(word) =>
word.firstLetter match {
case([a-c][A-C]) =>
case _ =>
}
}
Aber wie kann ich den ersten Buchstaben in Scala anstelle von Java abrufen? Wie drücke ich den regulären Ausdruck richtig aus? Ist dies innerhalb einer Fallklasse möglich ?
[a-cA-C]
diesen regulären Ausdruck.Traversable
(wieList
undArray
) konvertiert. Wenn Sie die ersten 3 Zeichen möchten, versuchen Sie es"my string".take(3)
für den ersten"foo".head
Antworten:
Sie können dies tun, weil reguläre Ausdrücke Extraktoren definieren, Sie jedoch zuerst das Regex-Muster definieren müssen. Ich habe keinen Zugriff auf eine Scala REPL, um dies zu testen, aber so etwas sollte funktionieren.
quelle
val Pattern = "[a-cA-C]".r
funktioniert nicht. Dies liegt daran, dass Match-Case verwendet wirdunapplySeq(target: Any): Option[List[String]]
, wodurch die passenden Gruppen zurückgegeben werden.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(_*) => }
.Seit Version 2.10 kann die String-Interpolationsfunktion von Scala verwendet werden:
Noch besser kann man reguläre Ausdrucksgruppen binden:
Es ist auch möglich, detailliertere Bindungsmechanismen festzulegen:
Ein beeindruckendes Beispiel dafür, was mit möglich
Dynamic
ist, finden Sie im Blog-Beitrag Einführung in Type Dynamic :quelle
$
Vorzeichens als Zeilenendmuster: Der Compiler beschwert sich über das Fehlen einer Zeichenfolgenbeendigung.case p.firstName.lastName.Map(...
Muster - wie um alles in der Welt lese ich das?Regex
jeder Überprüfung der Übereinstimmung eine neue Instanz erstellt wird. Und das ist eine ziemlich kostspielige Operation, bei der das Regex-Muster kompiliert wird.Wie Delnan betonte, hat das
match
Schlüsselwort in Scala nichts mit regulären Ausdrücken zu tun. Um herauszufinden, ob eine Zeichenfolge mit einem regulären Ausdruck übereinstimmt, können Sie dieString.matches
Methode verwenden. Um herauszufinden, ob eine Zeichenfolge mit einem a, b oder c in Klein- oder Großbuchstaben beginnt, sieht der reguläre Ausdruck folgendermaßen aus:Sie können diesen regulären Ausdruck als "eines der Zeichen a, b, c, A, B oder C gefolgt von irgendetwas" lesen (
.
bedeutet "beliebiges Zeichen" und*
bedeutet "null oder mehrmals", also ". *" Ist eine beliebige Zeichenfolge). .quelle
Um Andrews Antwort ein wenig zu erweitern : Die Tatsache, dass reguläre Ausdrücke Extraktoren definieren, kann verwendet werden, um die vom regulären Ausdruck übereinstimmenden Teilzeichenfolgen mithilfe von Scalas Mustervergleich sehr gut zu zerlegen, z.
quelle
[]
) zeigt das Caret Negation an,[^\s]
bedeutet also "Nicht-Leerzeichen".String.matches ist der Weg, um einen Mustervergleich im Sinne eines regulären Ausdrucks durchzuführen.
Abgesehen davon sieht word.firstLetter im echten Scala-Code folgendermaßen aus:
Scala behandelt Strings als eine Folge von Chars. Wenn Sie also aus irgendeinem Grund explizit das erste Zeichen des Strings abrufen und es abgleichen möchten, können Sie Folgendes verwenden:
Ich schlage dies nicht als allgemeine Methode für den Abgleich von Regex-Mustern vor, aber es entspricht Ihrem vorgeschlagenen Ansatz, zuerst das erste Zeichen eines Strings zu finden und es dann mit einem Regex abzugleichen.
EDIT: Um klar zu sein, die Art und Weise, wie ich dies tun würde, ist, wie andere gesagt haben:
Ich wollte nur ein Beispiel zeigen, das Ihrem ursprünglichen Pseudocode so nahe wie möglich kommt. Prost!
quelle
"Cat"(0).toString
könnte klarer geschrieben werden als"Cat" take 1
, imho.val r = "[A-Ca-c]".r ; "cat"(0) match { case r() => }
.Beachten Sie, dass der Ansatz aus der Antwort von @ AndrewMyers die gesamte Zeichenfolge mit dem regulären Ausdruck übereinstimmt, wodurch der reguläre Ausdruck an beiden Enden der Zeichenfolge mit
^
und verankert wird$
. Beispiel:Und ohne
.*
am Ende:quelle
val MY_RE2 = "(foo|bar)".r.unanchored ; "foo123" match { case MY_RE2(_*) => }
. Idiomatischer,val re
ohne alle Kappen.Zunächst sollten wir wissen, dass reguläre Ausdrücke separat verwendet werden können. Hier ist ein Beispiel:
Zweitens sollten wir beachten, dass die Kombination von regulären Ausdrücken mit Mustervergleich sehr leistungsfähig wäre. Hier ist ein einfaches Beispiel.
In der Tat ist der reguläre Ausdruck selbst bereits sehr mächtig; Das einzige, was wir tun müssen, ist, es von Scala mächtiger zu machen. Weitere Beispiele finden Sie im Scala-Dokument: http://www.scala-lang.org/files/archive/api/current/index.html#scala.util.matching.Regex
quelle