Сопоставление с регулярным выражением в Scala - PullRequest
31 голосов
/ 29 ноября 2011

Я довольно часто сопоставляю строки с регулярными выражениями. В Java:

java.util.regex.Pattern.compile ( "\ ш +"). Согласовани ( "this_is"). Соответствует

Уч. У Scala есть много альтернатив.

  1. "\\w+".r.pattern.matcher("this_is").matches
  2. "this_is".matches("\\w+")
  3. "\\w+".r unapplySeq "this_is" isDefined
  4. val R = "\\w+".r; "this_is" match { case R() => true; case _ => false}

Первый такой же тяжелый, как и код Java.

Проблема со вторым заключается в том, что вы не можете предоставить скомпилированный шаблон ("this_is".matches("\\w+".r")). (Это кажется анти-паттерном, так как почти каждый раз, когда есть метод, который использует регулярное выражение для компиляции, возникает перегрузка, которая принимает регулярное выражение).

Проблема с третьим состоит в том, что он злоупотребляет unapplySeq и, следовательно, является загадочным.

Четвертый - отличный вариант для разложения частей регулярного выражения, но он слишком тяжелый, если вам нужен только логический результат.

Мне не хватает простого способа проверить совпадения с регулярным выражением? Есть ли причина, по которой String#matches(regex: Regex): Boolean не определен? На самом деле, где определяется String#matches(uncompiled: String): Boolean?

Ответы [ 4 ]

33 голосов
/ 29 ноября 2011

Вы можете определить шаблон следующим образом:

scala> val Email = """(\w+)@([\w\.]+)""".r

findFirstIn вернет Some[String], если совпадает, или же None.

scala> Email.findFirstIn("test@example.com")
res1: Option[String] = Some(test@example.com)

scala> Email.findFirstIn("test")
rest2: Option[String] = None

Вы можете даже извлечь:

scala> val Email(name, domain) = "test@example.com"
name: String = test
domain: String = example.com

Наконец, вы также можете использовать обычный метод String.matches (и даже переработать ранее определенный Email Regexp:

scala> "david@example.com".matches(Email.toString)
res6: Boolean = true

Надеюсь, это поможет.

14 голосов
/ 29 ноября 2011

Для этой проблемы я создал небольшой шаблон «Прокачай мою библиотеку».Может быть, это поможет вам.

import util.matching.Regex

object RegexUtils {
  class RichRegex(self: Regex) {
    def =~(s: String) = self.pattern.matcher(s).matches
  }
  implicit def regexToRichRegex(r: Regex) = new RichRegex(r)
}

Пример использования

scala> import RegexUtils._
scala> """\w+""".r =~ "foo"
res12: Boolean = true
4 голосов
/ 19 марта 2015

Я обычно использую

val regex = "...".r
if (regex.findFirstIn(text).isDefined) ...

но я думаю, что это довольно неловко.

1 голос
/ 15 августа 2014

В настоящее время (август 2014 г., Scala 2.11) @ Ответ Дэвида говорит о норме.

Однако, похоже, r."..." строковый интерполятор может помочь с этим. См. Как сопоставить шаблон с использованием регулярного выражения в Scala?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...