【问题标题】:Parsing a string containing any chars解析包含任何字符的字符串
【发布时间】:2012-05-04 09:42:43
【问题描述】:

我正在努力让追随者工作。所以我有括号内的字符串。字符串可以包含任何字符,因此我要解析的字符串也可以包含括号。我认为正则表达式当前也匹配应该由

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

所以我假设解析器正确解析了第一部分,但在看到括号部分时失败了。

【问题讨论】:

  • 您需要用(也许)一个小示例来扩展这个问题,说明您正在尝试做什么以及什么不起作用,因为它只是不清楚从这个问题,因为它是目前形成的。例如:获取字符串输入(() 时会发生什么? 会发生什么?一个错误?出乎意料?
  • 使示例更加清晰。所以本质上我想解析括号内的任何内容。
  • 正则语言(以及正则表达式)不能用于解析嵌套括号:它们的表达力不够。您需要使用另一种技术,使用递归、自动机或解析器生成器。

标签: parsing scala parser-combinators


【解决方案1】:

解析嵌套结构的正确解决方案是使用递归,例如以下列方式:

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)  
   } 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-09
    • 2011-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多