エスケープ文字を含む可能性のある文字列を解析しようとしています。例を次に示します。
import qualified Data.Text as T
exampleParser :: Parser T.Text
exampleParser = T.pack <$> many (char '\\' *> escaped <|> anyChar)
where escaped = satisfy (\c -> c `elem` ['\\', '"', '[', ']'])
上記のパーサーは を作成しString
、それを にパックしText
ます。attoparsec が提供する効率的な文字列処理のための関数を使用して、上記のようなエスケープで文字列を解析する方法はありますか? のようstring
にscan
、、、、runScanner
_takeWhile
...
のようなものを解析すると、"one \"two\" \[three\]"
が生成されone "two" [three]
ます。
更新:
@epsilonhalbe のおかげで、自分のニーズに最適な一般化されたソリューションを見つけることができました。[..]
次の関数は、".."
、(..)
、 などの一致するエスケープ文字を検索しないことに注意してください。また、無効なエスケープ文字が見つかった場合は\
、リテラル文字として扱います。
takeEscapedWhile :: (Char -> Bool) -> (Char -> Bool) -> Parser Text
takeEscapedWhile isEscapable while = do
x <- normal
xs <- many escaped
return $ T.concat (x:xs)
where normal = Atto.takeWhile (\c -> c /= '\\' && while c)
escaped = do
x <- (char '\\' *> satisfy isEscapable) <|> char '\\'
xs <- normal
return $ T.cons x xs