Search code examples
haskellparsec

How to read exact N chars with Parsec?


I'm new to Haskell and Parsec. I wish to parse php-serialize format of string 's:numb:"string";' like

s:12:"123";6789012";

where number is count of chars. So, function looks like:

newtype PhpString = PhpString String

pString :: GenParser Char st PhpString
pString = do { string "s:"
        ; value1 <- many1 digit
        ; string ":\""
        ; value2 <- takeExactNChars (read value1) 
        ; string "\";"      
        ; return $ PhpString value2
    }
    where 
        takeExactNChars n = ???????

Solution

  • I would write it using replicateM from Control.Monad:

    import Text.ParserCombinators.Parsec
    import Control.Monad (replicateM)
    
    pString :: Parser String
    pString = do string "s:"
                 n <- fmap read (many1 digit)
                 string ":\""         -- Bug fix; you weren't picking up the colon
                 s <- replicateM n anyChar
                 string "\";"
                 return s
    

    Testing it in ghci:

    *Main> parse pString "" "s:12:\"123\";6789012\";"
    Right "123\";6789012"