我正努力跟进工作。所以我的括号内有字符串。字符串可以包含任何字符,因此我要解析的字符串也可以包含括号。我认为正则表达式当前也匹配应该由<〜“)”匹配的最后一个括号,因此解析失败。我在这里缺少什么?
private def parser: Parser[Any] = a ~ b ~ c ^^ {
<do stuff here>
}
private def a: Parser[String] = "\"[^\"]*\"".r | "[^(),>]*".r
private def b: Parser[String] = opt("(" ~> ".*".r <~ ")") ^^ {
case Some(y) => y.trim
case None => ""
}
private def c: Parser[String] = rep(".@" ~> "[^>.]*".r) ^^ (new String(_).trim)
这应该解析以下类型的字符串:
test0
test1.@attr
"test2"
"test3".@attr
test4..
test5..@attr
"test6..".@attr
"test7.@attr".@attr
test8(icl>uw)
test9(icl>uw).@attr
"test10..().@"(icl>uw).@attr
test11(icl>uw(agt>uw2,obj>uw3),icl>uw4(agt>uw5))
test12(icl>uw1(agt>uw2,obj>uw3),icl>uw4).@attr1.@attr2
test13(agt>thing,obj>role>effect)
所以“a”解析器解析字符串直到打开括号或。@ attr部分。 “b”解析器解析可选括号内的字符。 “c”解析可选的。@ attrs。
目前,我在包含括号部分的所有测试字符串上都收到类似的错误:
11:07:44.662 [main] DEBUG - Parsed: test8()
11:07:44.667 [main] ERROR - FAILURE parsing: test8(icl>uw) -- `)' expected but `i' found
所以我假设解析器正确地解析了第一部分,但是当它看到括号部分时失败了。
答案 0 :(得分:0)
解析嵌套结构的正确解决方案是使用递归,例如以下列方式:
val parser= "regex".r
@tailrec
def extract(string:String,foundTokens:List[String]=List.empty):List[String]={
parser.findFirstMatchIn(string) match {
case Some(parser(matchedValue)) => extract(matchedValue,matchedValue::foundedTokens)
case None=>foundTokens
}
基本上在每次调用函数时,将找到的标记附加到结果列表中,然后在匹配结果上启动函数。如果找不到,则返回找到的令牌。
如果每个子语句中可能有多个匹配,那么你应该寻找类似这样的过程:
def extract(string:String):Iterator[String]={
parser.findAllIn(string).flatMap{
item => extract(item)
}
}