Chciałbym znaleźć dopasowanie między pierwszą literą słowa a jedną z liter w grupie, takiej jak „ABC”. W pseudokodzie może to wyglądać mniej więcej tak:
case Process(word) =>
word.firstLetter match {
case([a-c][A-C]) =>
case _ =>
}
}
Ale jak mogę pobrać pierwszą literę w Scali zamiast w Javie? Jak poprawnie wyrazić wyrażenie regularne? Czy można to zrobić w ramach klasy sprawy ?
[a-cA-C]
tego wyrażenia regularnego.Traversable
(jakList
iArray
), jeśli chcesz pierwsze 3 znaki, spróbuj"my string".take(3)
, na pierwszy"foo".head
Odpowiedzi:
Możesz to zrobić, ponieważ wyrażenia regularne definiują ekstraktory, ale najpierw musisz zdefiniować wzorzec wyrażenia regularnego. Nie mam dostępu do REPL Scala, aby to przetestować, ale coś takiego powinno działać.
źródło
val Pattern = "[a-cA-C]".r
nie zadziała. Dzieje się tak, ponieważ używa przypadków dopasowaniaunapplySeq(target: Any): Option[List[String]]
, które zwraca pasujące grupy.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(_*) => }
.Od wersji 2.10 można korzystać z funkcji interpolacji ciągów Scali:
Jeszcze lepiej można wiązać grupy wyrażeń regularnych:
Możliwe jest również ustawienie bardziej szczegółowych mechanizmów wiązania:
Imponujący przykład tego, co jest możliwe dzięki,
Dynamic
pokazano w poście na blogu Wprowadzenie do typu dynamicznego :źródło
$
znaku jako wzorca końca linii: kompilator narzeka na brak zakończenia łańcucha.case p.firstName.lastName.Map(...
wzór - jak mam to przeczytać?Regex
za każdym razem, gdy sprawdzane jest dopasowanie. Jest to dość kosztowna operacja, która wymaga kompilacji wzorca regex.Jak zauważył delnan,
match
słowo kluczowe w Scali nie ma nic wspólnego z wyrażeniami regularnymi . Aby dowiedzieć się, czy ciąg pasuje do wyrażenia regularnego, możesz użyćString.matches
metody. Aby dowiedzieć się, czy ciąg znaków zaczyna się od a, b lub c małymi czy dużymi literami, wyrażenie regularne będzie wyglądać następująco:Możesz odczytać to wyrażenie regularne jako „jeden ze znaków a, b, c, A, B lub C, po którym następuje cokolwiek” (
.
oznacza „dowolny znak” i*
oznacza „zero lub więcej razy”, więc „. *” To dowolny ciąg) .źródło
Aby rozwinąć nieco odpowiedź Andrew : Fakt, że wyrażenia regularne definiują ekstraktory, można wykorzystać do bardzo ładnego dekompozycji podciągów dopasowanych przez wyrażenie regularne, używając dopasowania wzorców Scali, np .:
źródło
[]
), daszek wskazuje na negację, więc[^\s]
oznacza „bez białych znaków”.String.matches to sposób na dopasowanie wzorców w sensie wyrażenia regularnego.
Na marginesie, word.firstLetter w prawdziwym kodzie Scala wygląda tak:
Scala traktuje ciągi jako sekwencję znaków Char, więc jeśli z jakiegoś powodu chciałeś jawnie pobrać pierwszy znak ciągu i dopasować go, możesz użyć czegoś takiego:
Nie proponuję tego jako ogólnego sposobu dopasowywania wzorców wyrażeń regularnych, ale jest to zgodne z proponowanym przez Ciebie podejściem, aby najpierw znaleźć pierwszy znak ciągu, a następnie dopasować go do wyrażenia regularnego.
EDYCJA: Żeby było jasne, sposób bym to zrobił, jak powiedzieli inni:
Chciałem tylko pokazać przykład jak najbliższy początkowemu pseudokodowi. Twoje zdrowie!
źródło
"Cat"(0).toString
można by jaśniej zapisać jako"Cat" take 1
, imho.val r = "[A-Ca-c]".r ; "cat"(0) match { case r() => }
.Zauważ, że podejście z odpowiedzi @ AndrewMyers dopasowuje cały ciąg do wyrażenia regularnego, czego efektem jest zakotwiczenie wyrażenia regularnego na obu końcach ciągu przy użyciu
^
i$
. Przykład:I bez
.*
końca:źródło
val MY_RE2 = "(foo|bar)".r.unanchored ; "foo123" match { case MY_RE2(_*) => }
. Bardziej idiomatycznie,val re
bez wszystkich czapek.Najpierw powinniśmy wiedzieć, że wyrażenie regularne może być używane oddzielnie. Oto przykład:
Po drugie, powinniśmy zauważyć, że połączenie wyrażenia regularnego z dopasowywaniem wzorców byłoby bardzo potężne. Oto prosty przykład.
W rzeczywistości samo wyrażenie regularne jest już bardzo potężne; Jedyne, co musimy zrobić, to uczynić go potężniejszym za pomocą Scali. Oto więcej przykładów w dokumencie Scala: http://www.scala-lang.org/files/archive/api/current/index.html#scala.util.matching.Regex
źródło