Scala模式匹配重复的正则表达式组

时间:2019-02-20 13:32:26

标签: regex scala pattern-matching

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

modularLarge.tintColor = UIColor.red

除了

let modularLarge = CLKComplicationTemplateModularLargeStandardBody()    
modularLarge.tintColor = .red //do this

modularLarge.headerTextProvider = CLKSimpleTextProvider(text: dateText.capitalized)
modularLarge.headerTextProvider.tintColor = self.tintColor

modularLarge.body1TextProvider = CLKSimpleTextProvider(text: timeText)
modularLarge.body2TextProvider = CLKSimpleTextProvider(text: "00:00")

handler(CLKComplicationTimelineEntry(date: Date(),complicationTemplate: modularLarge))

已更新:

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

1 个答案:

答案 0 :(得分:2)

使用模式匹配时,您只能在字符串中获取一个匹配项。因此,一种解决方案是直接使用regex API。

解决方案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 demo

解决方案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 demo

详细信息

  • (?:\G(?!^)\s*,\s*|(?=\w+(?:,\s*\w+)+))-两种选择之一:
    • \G(?!^)\s*,\s*-上一场比赛的结尾,然后是一个用可选空格括起来的逗号
    • |-或
    • (?=\w+(?:\s*,\s*\w+)+)-位置后跟1+个单词字符,然后1个重复的逗号加上可选的空格,再加上1+个单词字符
  • (\w+)-第1组:一个或多个单词字符(字母,数字或_

请参见regex demo

模式匹配只能找到一个匹配项

请注意,您可以使用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)

请参见another Scala demo

注意:

  • 在这里,.unanchored对于返回部分匹配是必需的
  • 整个模式都被捕获组包裹着,因为我们需要使用该组来访问match块内的找到的文本
  • .split("""\s*,\s*""")使用逗号分隔并以0+空格分隔找到的文本
  • 如果没有匹配项,case _ => List("")将返回一个空列表。