2012-04-23 29 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) 

これは、文字列次のような解析することになっている:。だから、「」パーサは開き括弧または@ attrの部分まで文字列を解析し

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) 

を。 "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

あなたは小さな**例(多分)でこの質問を拡張する必要があります**:

複数の一致が各サブトークン内の可能性がある場合は、その後、あなたは、このような手順を探してくださいそれが現在形成されているように、疑問からはっきりしていないので、それが働いていないことをやろうとしています。 たとえば、文字列入力 '(()'を取得するときに何が起こるのでしょうか?エラー?予期しない何か? –

+0

例を少し明確にしたので、基本的にはかっこの中にあるもの – Kitanotori

+0

ネストしたかっこの解析には、通常の言語(したがって正規表現)を使用することはできません。表現力は十分ではありません。再帰、オートマトン、パーサジェネレータのいずれかを使用して別の手法を使用する必要があります。 – esope

答えて

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