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