scala模式匹配重复正则表达式组

rbpvctlc  于 2021-07-14  发布在  Java
关注(0)|答案(1)|浏览(310)

如何通过regex模式从一些重复的值中提取列表,例如。

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(",")

更新时间:
我对模式匹配特别感兴趣,因为输入字符串值中可能有多个列表

py49o6xq

py49o6xq1#

使用模式匹配,您只能在字符串中获取一个匹配项。因此,解决方案是直接使用regexapi。
解决方案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组:一个或多个单词字符(字母、数字或 _ 秒)
查看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("") 将返回一个空列表。

相关问题