如何使用 Parsec 按特定字符串分隔字符串
How to use Parsec to separate a string by a specific string
我正在学习parsec,刚好遇到如下情况。我想通过特定的 String
将 String
分成 [String]
;例如,我得到 "abcSEPdef
,分隔符是 "SEP",所以,在解析之后,我应该得到一个 ["abc","def"]
我认为解析器应该看起来像 sepBy a_parser (string "SEP")
;但是,我不知道 a_parser
应该是什么样子。
找到 "SEP" 的否定,并让该解析器成为 parseNonSEP。
理论上保证parseNonSEP属于正则语言的范畴,因为正则语言在否定下是封闭的,应该有直接的方式来实现。
然后,
sepBy pareseNonSEP(字符串 "SEP")
会完成任务的。
好吧,我上面提到的是一个相当理论的方法:)
更多 parsec 风格的方法可能是在不实际消耗输入的情况下提前查看输入标记列表 and/or 使用回溯,例如 try、notFollowedBy、lookAhead。
见
http://hackage.haskell.org/package/parsec-3.1.9/docs/Text-Parsec-Combinator.html
使用 manyTill
几次即可:
uptoSEP = manyTill anyChar (eof <|> (string "SEP" >> return ()))
splitSEP = manyTill uptoSEP eof
例如:
ghci> parseTest splitSEP "abcSEPdefSEPxyz"
["abc","def","xyz"]
您需要启用 {-# LANGUAGE NoMonomorphismRestriction #-}
pragma。
我终于找到了一种将 split
包合并到 parsec
中的方法:
module Sep where
import Text.ParserCombinators.Parsec
import qualified Data.List.Split as DLS
mysep :: String -> Parser [String]
mysep sep = getInput >>= return . DLS.splitOn sep
replace-megaparsec
包有一个
sepCap
用于拆分字符串和捕获分隔的组合器。
import Replace.Megaparsec
import Text.Megaparsec
parseTest (sepCap (chunk "SEP" :: Parsec Void String String)) "abcSEPdef"
[Left "abc",Right "SEP",Left "def"]
我正在学习parsec,刚好遇到如下情况。我想通过特定的 String
将 String
分成 [String]
;例如,我得到 "abcSEPdef
,分隔符是 "SEP",所以,在解析之后,我应该得到一个 ["abc","def"]
我认为解析器应该看起来像 sepBy a_parser (string "SEP")
;但是,我不知道 a_parser
应该是什么样子。
找到 "SEP" 的否定,并让该解析器成为 parseNonSEP。 理论上保证parseNonSEP属于正则语言的范畴,因为正则语言在否定下是封闭的,应该有直接的方式来实现。
然后,
sepBy pareseNonSEP(字符串 "SEP")
会完成任务的。
好吧,我上面提到的是一个相当理论的方法:) 更多 parsec 风格的方法可能是在不实际消耗输入的情况下提前查看输入标记列表 and/or 使用回溯,例如 try、notFollowedBy、lookAhead。
见
http://hackage.haskell.org/package/parsec-3.1.9/docs/Text-Parsec-Combinator.html
使用 manyTill
几次即可:
uptoSEP = manyTill anyChar (eof <|> (string "SEP" >> return ()))
splitSEP = manyTill uptoSEP eof
例如:
ghci> parseTest splitSEP "abcSEPdefSEPxyz"
["abc","def","xyz"]
您需要启用 {-# LANGUAGE NoMonomorphismRestriction #-}
pragma。
我终于找到了一种将 split
包合并到 parsec
中的方法:
module Sep where
import Text.ParserCombinators.Parsec
import qualified Data.List.Split as DLS
mysep :: String -> Parser [String]
mysep sep = getInput >>= return . DLS.splitOn sep
replace-megaparsec
包有一个
sepCap
用于拆分字符串和捕获分隔的组合器。
import Replace.Megaparsec
import Text.Megaparsec
parseTest (sepCap (chunk "SEP" :: Parsec Void String String)) "abcSEPdef"
[Left "abc",Right "SEP",Left "def"]