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.
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"