在符合条件的特定字符处分割字符串

时间:2018-07-10 08:34:06

标签: string scala split

我将Vector写入文本文件。 向量((a1,b1,c1),(a2,b2,c2),........) 这是一个长字符串,我可以从文本文件中读取该字符串并将其存储在String变量中,并说v。我不想将字符串“ v”分割为所有逗号,而是仅将元组分隔为逗号,即,在每个括号的右括号后元组成数组。 如何在Scala中做到这一点? (考虑到每个元组的中间元素也不是元组,并且在开始和结尾处都不包含任何括号。)

3 个答案:

答案 0 :(得分:4)

您可以尝试编写自己的解析器。这是一个示例:

import scala.util.parsing.combinator.RegexParsers

class Parser extends RegexParsers {

  def id = "[a-z0-9]+".r

  def value: Parser[Any] = id | tuple

  def tuple = "(" ~ rep1sep(value, ",") ~ ")" ^^ {
    case _ ~ List(v1, v2, v3) ~ _ => (v1, v2, v3)
  }

  def tuples = rep1sep(tuple, ",")

  def vector = "Vector(" ~ tuples ~ ")" ^^ {
    case _ ~ tuples ~ _ => tuples
  }
}

val string = "Vector((a1,(aa1, (aaa1, bbb1, ccc1), cc1),c1),(a2,b2,c2),(a3,b3,c3))"
val parser = new Parser
val result = parser.parseAll(parser.vector, string)
val res = result.get

产生:

res: List[(Any, Any, Any)] = List((a1,(aa1,(aaa1,bbb1,ccc1),cc1),c1), (a2,b2,c2), (a3,b3,c3))

答案 1 :(得分:2)

我尚未对此进行全面测试,但这应该可以工作:

v.split(",?(?=\\([\\w,]*\\))")

它可能还会得到一些空白条目,并且Vector()仍然存在,并且如果发生这种情况,您需要执行以下操作:

val v = """Vector((a1,b1,c1),(a2,b2,c2),(a3,b3,c3))"""

v.replaceAll("Vector\\((.*)\\)", "$1")
  .split(",?(?=\\([\\w,]*\\))")
  .filter(_.trim != "")

这有点混乱,可以清除它,但应该可以。关于正则表达式的工作方式:

  • ,?-可选逗号(可选,用?表示)
  • (?= .... )-前瞻性
  • \\( .... \\)-逃脱的括号(括号是正则表达式的特殊字符)
  • [\\w,]*-任何单词字符或逗号,任意次数

注意:如果您要使用split,则可以使用此解决方案。我建议使用Scala Regex库,因为它会更整洁(尽管我不确定每种方法对性能的影响)。

另外请注意:在常规Regex中,您只需要一个反斜杠即可转义一个字符,而Scala需要两个反斜杠。

答案 2 :(得分:0)

使用 regex 来检测元组(假设元组中没有括号),并且远离数组,但使用类似于list的方法:     

val regex = "\\([^\\(\\)]+?\\)".r
val string = "Vector((a1,b1,c1),(a2,b2,c2),(a3,b3,c3))"
val iterator = regex.findAllIn(string)
iterator.toList.foreach(println)

产生:

(a1,b1,c1)
(a2,b2,c2)
(a3,b3,c3)

see and play here