Сопоставление регулярных выражений Scala с интерполяцией строк - PullRequest
0 голосов
/ 25 декабря 2018

В Scala 2.10 мы можем определить новый метод r с помощью StringContext следующим образом:

implicit class RegexContext(sc: StringContext) {
  def r = new Regex(sc.parts.mkString, sc.parts.tail.map(_ => "x"): _*)
}

Затем мы можем легко определить шаблон регулярного выражения после ключевого слова case, например:

"123" match { 
   case r"\d+" => true 
   case _ => false 
}

Мне не понятно, как работает реализация внутри неявного класса RegexContext

Может кто-нибудь объяснить мне реализацию метода r, особенно sc.parts.tail.map(_ => "x"): _*?

Реализациявзято из Как сопоставить шаблон с использованием регулярного выражения в Scala?

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Конструктор Regex принимает два аргумента.

new Regex (regex: String, groupNames: String *)

The *Параметр 1010 * является переменным, поэтому он (они) на самом деле является необязательным, и в этом случае его следует оставить пустым, поскольку этот код groupNames довольно бесполезен.

Давайте рассмотрим, что предполагается groupNamesсделать.Мы начнем без groupNames.

val rx = new Regex("~(A(.)C)~")  // pattern with 2 groups, no group names
rx.findAllIn("~ABC~").group(0) //res0: String = ~ABC~
rx.findAllIn("~ABC~").group(1) //res1: String = ABC
rx.findAllIn("~ABC~").group(2) //res2: String = B
rx.findAllIn("~ABC~").group(3) //java.lang.IndexOutOfBoundsException: No group 3

А теперь с groupNames.

val rx = new Regex("~(A(.)C)~", "x", "y", "z")  // 3 groups named
rx.findAllIn("~ABC~").group("x") //res0: String = ABC
rx.findAllIn("~ABC~").group("y") //res1: String = B
rx.findAllIn("~ABC~").group("z") //java.lang.IndexOutOfBoundsException: No group 3

Так почему же sc.parts.tail.map(_ => "x"): _* так бесполезен?Во-первых, потому что количество созданных имен не связано с количеством групп в шаблоне, но также потому, что оно использует одну и ту же строку, "x", для каждого имени, которое оно указывает.Это имя подходит только для последней названной группы.

val rx = new Regex("~(A(.)C)~", "x", "x")  // 2 groups named
rx.findAllIn("~ABC~").group("x") //res0: String = B (i.e. group(2))

... и ...

val rx = new Regex("~(A(.)C)~", "x", "x", "x")  // 3 groups named
rx.findAllIn("~ABC~").group("x") //java.lang.IndexOutOfBoundsException: No group 3
0 голосов
/ 25 декабря 2018

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

scala 2.13.0-M5> implicit class R(sc: StringContext) { def r = sc.parts.mkString.r }
defined class R

scala 2.13.0-M5> "hello" match { case r"hell.*" => }

Сравните:

scala 2.13.0-M5> implicit class R(sc: StringContext) { def r = sc.parts.mkString("(.*)").r }
defined class R

scala 2.13.0-M5> "hello" match { case r"hell$x" => x }
res5: String = o
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...