Подтвердить что ты не робот

Соответствие регулярному выражению в Scala

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

java.util.regex.Pattern.compile( "\ W +" ). Matcher ( "this_is" ). Соответствует

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

  • "\\w+".r.pattern.matcher("this_is").matches
  • "this_is".matches("\\w+")
  • "\\w+".r unapplySeq "this_is" isDefined
  • 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 определено?

4b9b3361

Ответ 1

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

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

findFirstIn вернет Some[String], если он соответствует, или None.

scala> Email.findFirstIn("[email protected]")
res1: Option[String] = Some([email protected])

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

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

scala> val Email(name, domain) = "[email protected]"
name: String = test
domain: String = example.com

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

scala> "[email protected]".matches(Email.toString)
res6: Boolean = true

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

Ответ 2

Я создал небольшой шаблон "Pimp my Library" для этой проблемы. Возможно, это поможет вам.

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

Ответ 3

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

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

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