我正在尝试使用由多个字符组成的分隔符来分隔字符串,但问题是每个字符都可以在非分隔字符串中自行出现。例如,我有foo*X*bar*X*baz
,其中分隔符为*X*
,因此我想获得[foo, bar, baz]
,但其中每个都可以包含*
或X
我试过了
sepBy (many anyChar) delimiter
但这只是吞下整个字符串,如果我这样做,则会给"foo*X*bar*X*baz"
sepBy anyChar (optional delimiter)
它会正确过滤掉分隔符,但不对列表进行分区,返回"foobarbaz"
。我不知道我可以尝试哪种其他组合。
答案 0 :(得分:3)
也许你想要这样的东西,
tok = (:) <$> anyToken <*> manyTill anyChar (try (() <$ string sep) <|> eof)
anyToken
阻止我们在输入结束时永远循环,try
让我们避免过度渴望使用分隔符。
测试的完整代码,
module ParsecTest where
import Control.Applicative ((<$), (<$>), (<*>))
import Data.List (intercalate)
import Text.Parsec
import Text.Parsec.String
sep,msg :: String
sep = "*X*"
msg = intercalate "*X*" ["foXo", "ba*Xr", "bX*az"]
tok :: Parser String
tok = (:) <$> anyToken <*> manyTill anyChar (try (() <$ string sep) <|> eof)
toks :: Parser [String]
toks = many tok
test :: Either ParseError [String]
test = runP toks () "" msg