2012-04-23 108 views
2

我试图让下面的工作。所以我有括号内的字符串。字符串可以包含任何字符,因此我想要解析的字符串也可以包含括号。我认为当前正则表达式也匹配最后一个应该与<〜“)”匹配的括号,因此解析失败。我在这里错过了什么?解析包含任何字符的字符串

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("[email protected]" ~> "[^>.]*".r) ^^ (new String(_).trim) 

这应该分析以下类型的字符串:

test0 
[email protected] 
"test2" 
"test3"[email protected] 
test4.. 
[email protected] 
"test6.."[email protected] 
"[email protected]"[email protected] 
test8(icl>uw) 
test9(icl>uw)[email protected] 
"test10..()[email protected]"(icl>uw)[email protected] 
test11(icl>uw(agt>uw2,obj>uw3),icl>uw4(agt>uw5)) 
test12(icl>uw1(agt>uw2,obj>uw3),icl>uw4)[email protected]@attr2 
test13(agt>thing,obj>role>effect) 

因此,“一”解析器解析字符串,直到开括号或@ 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 

所以我假设分析器正确分析的第一部分,但未能当它看到括号部分。

+2

你需要扩大与(也许是)一个小**例如这个问题你**正在努力去做,那是不是在起作用,因为目前形成的问题尚不清楚。 例如:得到字符串输入时会发生什么?(()'?发生了什么?出错?有什么意外? – 2012-04-23 19:14:13

+0

让示例更清楚一点。因此,本质上我想解析括号内的任何内容 – Kitanotori 2012-04-24 10:54:22

+0

正则语言(以及正则表达式)不能用于解析嵌套圆括号:它们表达不够充分,需要使用另一种技术,使用递归或自动机或解析器生成器。 – esope 2012-05-23 23:00:27

回答

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 
} 

其中基本上在每次调用该函数,你找到的令牌追加到结果的列表和你启动比赛结果的功能。当你再也找不到时,你会返回找到的标记。

如果多个匹配可能每个subtoken里面,那么你应该寻找这样一个过程:

def extract(string:String):Iterator[String]={ 
    parser.findAllIn(string).flatMap{ 
     item => extract(item) 
    } 
}