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(".@" ~> "[^>.]*".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

したがって、パーサーは最初の部分を正しく解析したと思いますが、括弧の部分を見ると失敗しました。

4

1 に答える 1

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)  
   } 
}
于 2012-05-08T16:59:24.453 に答える