Search code examples
haskellparsec

Is there any way to express end with in Parsec?


I am trying to implement some parse function which only accept some specific character at the end of this string which would be .*!$ if the give character is ! using regular expression.

I have tried to use the following function, but it does not work, as it will consume characters before matching the end.

endWith :: Char -> Parser ()
endWith x = many anyChar >> char x >> return ()

One thing to note is: the expected output for "ab!cd!" is ("ab!cd!", "") and "ab!cd" should not be consumed by this parser at all, as it is not end with !. The all or northing is very important when using <|>

Is it possible using Parsec? I suppose some advanced combination is in need.


Solution

  • Is this what you are looking for?

    import Text.Parsec
    import Text.Parsec.String
    
    endWith :: Char -> Parser String
    endWith x = do cs <- many anyChar -- consume rest of input
                   case cs of
                     [] -> fail "expecting !"
                     _  -> if last cs == '!' then return cs
                                             else fail "did not end in !"
    
    test1 = parseTest (endWith '!') "This is a test!"
    test2 = parseTest (endWith '!') "ab!cd!"
    test3 = parseTest (endWith '!') "ab!cd"