从scala字符串中提取标记的快速方法

时间:2016-07-14 08:44:57

标签: regex string scala

给定一个scala字符串,其中包含一组键值对(键值对的类型顺序不固定,键值对的数量不固定):

val s = "key1: val1, key2: (val2.1, val2.2, val2.3), key3: (), key4: val4"

我需要把它们拉成一个不可变的地图,如:

Map("key1" -> "val1",
  "key2" -> "(val2.1, val2.2, val2.3)",
  "key3" -> "()",
  "key4" -> "val4")

我试过这个:

val kvMap = s.split(", ").map(_.split(": ")).map(t => t(0) -> t(1)).toMap

但是失败了,因为在括号中和键值对之间使用相同的分隔符(逗号)。

我可以使用迭代使用堆栈但是想避免这种情况。

我也尝试过写一个可以帮助我做到这一点的正则表达式,但可以让它只能用于1对:

scala>  val MyPattern = "([^=]*):(.*)".r
Pattern: scala.util.matching.Regex = ([^=]*):(.*)
                           ^
scala> val MyPattern(k, v) = "key: value"
k: String = key
v: String = " value"

我正在寻找一种功能性的方法来完成这项操作。

1 个答案:

答案 0 :(得分:5)

如果你的键值对没有嵌套的括号,你可以使用正则表达式用逗号+空格分割,除了()以外的任何字符都不跟{{{ 1}}:

)

请参阅regex demo

<强>解释

  • """, (?![^()]*\))""".r - 只有在......
  • 后才能匹配逗号和空格
  • , - 未跟随非(?![^()]*\))和非)(0次或更多次)后跟文字)(即,如果没有跟随某事+ ))。

如果您想尝试匹配的方法:

)

请参阅this demo

<强>详情:

  • """([^=:]*):\s*(.*?),?\s*(?=$|\w+:)""".r - 第1组捕获除([^=:]*)=以外的0 +个字符(可能:应替换为*,因为密钥不能是空的)
  • + - 一个0 +空格的冒号
  • :\s* - 任意字符,但换行符尽可能少(第2组,(.*?),?\s*),后跟可选的(.*?)和0+空格......
  • , - 跟随字符串结尾或1个单词字符和冒号。
相关问题