Scala шаблон соответствует повторяющимся группам регулярных выражений - PullRequest
0 голосов
/ 20 февраля 2019

Как я могу извлечь список из некоторых повторяющихся значений по шаблонам регулярных выражений, например,

val fruits = "fruits: apple, orange, banana"
fruits match {
  case regex(fruits) => // where `fruits` is `List[String] = List(apple, orgran, banana)`
}

Кроме

case regex(rawFruits) => rawFruits.split(",")

ОБНОВЛЕНО:

Мне интересноособенно в сопоставлении с образцом, поскольку во входной строке может быть несколько списков

1 Ответ

0 голосов
/ 20 февраля 2019

При сопоставлении с образцом вы можете получить только одно совпадение в строке.Таким образом, решение будет заключаться в прямом использовании API-интерфейса regex.

Solutoion 1: простой двухшаговый способ

Вы можете захватить все вхождения word+one or more sequences of 1+ spaces and then words, а затемразбить совпадения с помощью шаблона spaces-comma-spaces:

val fruits = "fruits: apple, orange, banana and vegetables: carrots, potatos, cabbage"
val regex = """\w+(?:,\s*\w+)+""".r
val results = (regex findAllIn fruits).map(_ split """\s*,\s*""").toList
for (l <- results) println(l.toList)

Вывод:

List(apple, orange, banana)
List(carrots, potatos, cabbage)

См. демонстрационную версию Scala .

Решение 2: «одно регулярное выражение, чтобы управлять ими всеми»

Вы можете использовать одно регулярное выражение для захвата любого отдельного слова, если слово является частью строки слов, разделенных запятыми, используя findAllIn:

val fruits = "fruits: apple, orange, banana"
val regex = """(?:\G(?!^)\s*,\s*|(?=\w+(?:,\s*\w+)+))(\w+)""".r
val results = (regex findAllIn fruits).matchData.map(_ group 1).toList
println(results)
// => List(apple, orange, banana)

См. Демонстрационную версию Scala

Подробности

  • (?:\G(?!^)\s*,\s*|(?=\w+(?:,\s*\w+)+)) - один из двух вариантов:
    • \G(?!^)\s*,\s* - конец предыдущего матча, а затем запятая с необязательными пробелами
    • | - или
    • (?=\w+(?:\s*,\s*\w+)+) - местоположение, за которым следуетс 1+ символами слова, а затем с 1+ повторениями запятой, заключенной в необязательные пробелы, а затем с 1+ символами слова
  • (\w+) - Группа 1: одно или несколько символов слова(буквы, цифрыs или _ s)

См. демонстрационную версию regex .

Соответствие шаблону, чтобы найти только одно совпадение

Обратите внимание, что вы можете проанализировать эту строку, используя блок match, чтобы извлечь эту строку слов, разделенных запятыми, а затем разделить их:

val fruits = "fruits: apple, orange, banana."
val regex = """(\w+(?:\s*,\s*\w+)+)""".r.unanchored
val results = fruits match {
  case regex(m) => m.split("""\s*,\s*""").toList
  case _ => List("")
}
println(results) // => List(apple, orange, banana)

См. еще одну демонстрацию Scala .

Примечание:

  • Здесь .unanchored необходимо для возврата частичного совпадения
  • Весь шаблон обернут группой захвата, так как нам нужен доступ кнайденный текст внутри блока match с использованием этой группы
  • .split("""\s*,\s*""") разделяет найденный текст запятой, заключенной в 0+ пробелов
  • Если совпадений нет, case _ => List("") вернетпустой список.
...