haskell
  • parsec
  • 2016-06-20 12 views 0 likes 
    0

    私はちょうどparsecを使い始めました。私は単純なことをやろうとしています。Parsecでエスケープされた区切り文字を解析する

    this parsec tutorialに示すように、キー値文字列を区切りたいと思います。

    たとえば、文字列FirstN=Tom&LastN=Brady[["FirstN","Tom"],["LastN","Brady"]]となります。

    これは簡単ですが、文字列内の'='文字をエスケープすることも許可します。たとえば、文字列Equation=1+1\\=2には[["Equation", "1+1\\=2"]](または[["Equation","1+1=2"]])とする必要がありますが、どちらが最善かは決まっていません。

    簡単な例について解析コードは以下の通りです:

    kvParser :: String -> Either ParseError [[String]] 
    kvParser input = parse kvString "Error text?" input 
    
    kvString = sepBy kvVal (char '&') 
    kvVal = sepBy (many (noneOf "=&")) (char '=') 
    

    私は(char '=')値を変更する必要がありますが、私は方法がわからないと思うエスケープ=を許可します。誰にも何か提案はありますか?

    おかげ

    編集:最終作業パーサは私もtryコンビネータを使用して動作するように、次しまった

    kvParser :: String -> Either ParseError [[String]] 
    kvParser input = parse kvString "Error text?" input 
    
    kvString = sepBy kvVal (char '&') 
    kvVal = sepBy (many kvChar) (char '=') 
    kvChar = noneOf "\\&=" <|> (char '\\' >> anyChar) 
    

    です。

    kvParser :: String -> Either ParseError [[String]] 
    kvParser input = parse kvString "Error text?" input 
    
    kvString = sepBy kvVal (char '&') 
    kvVal = sepBy (many kvChar) (char '=') 
    kvChar = try (string "\\=" >> return '=') <|> noneOf "&=" 
    

    答えて

    3

    セパレータは問題ありません。あなたが望むのは、キーまたは値の一部として\=を受け入れることです。代わりに

    noneOf "=&" 
    

    のあなたはnoneOfは、そうでない場合は右のパーサは受け入れ(およびスキップ)します、バックスラッシュをバックスラッシュではない何かを受け入れ、維持する、ある

    (noneOf "\\&" <|> (char '\\' >> anyChar)) 
    

    を試してみてくださいそれに続くキャラクター。それはセパレータとして検出されないようにする必要があります。

    +0

    私は 'noneOf" =& "'(noneOf "\\&" (char '\\' >> anyChar)) 'で置き換えましたが、今は' = 'で区切りません。それは '\\\'値を食べます。 – user668074

    +0

    OK、おそらく、 '='を 'noneOf'文字列に追加する必要があります。私は個人的にそれを実際にテストしていないことを認めます。私は 'noneOf" \\ =& "'は動作すると思う... – MathematicalOrchid

    +0

    ありがとう、これは動作します。私は働く別の方法があります。 – user668074

    関連する問題