如何使用 Parsec (Haskell) 根据密钥标记将值插入字符串?
How can I interpolate values into a string based on a key token using Parsec (Haskell)?
我是解析领域的新手,有一个看似相当简单的问题:
我有一个长字符串,由 Chunk
的普通文本和 Key
编码的 <<key-label>>
.
组成
data Merge a = Chunk a
| Key a
deriving (Show)
key :: Parser (Merge String)
key = Key <$> between (string "<<") (string ">>") (many1 letter)
chunk :: Parser (Merge String)
chunk = Chunk <$> many1 anyChar
prose = many1 $ key <|> chunk
ex = parseTest prose "hi <<x>> ! Do you like <<y>>?"
-- Returns:
-- [Chunk "hi <<x>> ! Do you like <<y>>?"]
-- I'd like:
-- [Chunk "hi ", Key "x", Chunk " !", ...]
我想用值替换这些键,但我可以解决这个问题,如果我可以将字符串解析为我的标记,IE String -> [Merge]
。
我已经深入到 lexing/parsing 的无限深度,虽然我希望最终能学会所有这些,但现在有解决这个问题的指导吗?
这是我尝试的最简单的实例化,尽管我尝试过单独传递数据,包括单独的 lexing/parsing 步骤,并且我 喜欢 使用parsec
而不是更具体的插值库。
您可以使用 notFollowedBy
表示您希望一个块包含一个
字符,只要它不是键。 notFollowedBy
不消费
输入所以 prose
仍会继续将密钥再次解析为它自己的项目。
chunk = Chunk <$> many1 (notFollowedBy key >> anyChar)
这将允许像 aaa<<bbbbbb
这样的东西被解析为一个块,
一直走到文件末尾,没有找到结束符
>>
,决定它一定不是钥匙,因此它可以
成为大块的一部分。
如果您希望 <<
始终作为密钥的开头并且在以下情况下失败
它没有关闭,禁止来自块的 <<
:
chunk = Chunk <$> many1 (notFollowedBy (string "<<") >> anyChar)
replace-megaparsec
是一个用于使用解析器进行搜索和替换的库。这
搜索和替换功能是
streamEdit
.
import Replace.Megaparsec
import Text.Megaparsec
import Text.Megaparsec.Char
import Data.Char
key = between (string "<<") (string ">>") (many letterChar) :: Parsec Void String String
editor k = "Key " ++ (fmap toUpper k)
streamEdit key editor "hi <<x>> ! Do you like <<y>>?"
"hi Key X ! Do you like Key Y?"
你也可以用
sepCap
parser combinator,其中 returns 等同于 [Merge]
的结构
您正在尝试构建。
我是解析领域的新手,有一个看似相当简单的问题:
我有一个长字符串,由 Chunk
的普通文本和 Key
编码的 <<key-label>>
.
data Merge a = Chunk a
| Key a
deriving (Show)
key :: Parser (Merge String)
key = Key <$> between (string "<<") (string ">>") (many1 letter)
chunk :: Parser (Merge String)
chunk = Chunk <$> many1 anyChar
prose = many1 $ key <|> chunk
ex = parseTest prose "hi <<x>> ! Do you like <<y>>?"
-- Returns:
-- [Chunk "hi <<x>> ! Do you like <<y>>?"]
-- I'd like:
-- [Chunk "hi ", Key "x", Chunk " !", ...]
我想用值替换这些键,但我可以解决这个问题,如果我可以将字符串解析为我的标记,IE String -> [Merge]
。
我已经深入到 lexing/parsing 的无限深度,虽然我希望最终能学会所有这些,但现在有解决这个问题的指导吗?
这是我尝试的最简单的实例化,尽管我尝试过单独传递数据,包括单独的 lexing/parsing 步骤,并且我 喜欢 使用parsec
而不是更具体的插值库。
您可以使用 notFollowedBy
表示您希望一个块包含一个
字符,只要它不是键。 notFollowedBy
不消费
输入所以 prose
仍会继续将密钥再次解析为它自己的项目。
chunk = Chunk <$> many1 (notFollowedBy key >> anyChar)
这将允许像 aaa<<bbbbbb
这样的东西被解析为一个块,
一直走到文件末尾,没有找到结束符
>>
,决定它一定不是钥匙,因此它可以
成为大块的一部分。
如果您希望 <<
始终作为密钥的开头并且在以下情况下失败
它没有关闭,禁止来自块的 <<
:
chunk = Chunk <$> many1 (notFollowedBy (string "<<") >> anyChar)
replace-megaparsec
是一个用于使用解析器进行搜索和替换的库。这
搜索和替换功能是
streamEdit
.
import Replace.Megaparsec
import Text.Megaparsec
import Text.Megaparsec.Char
import Data.Char
key = between (string "<<") (string ">>") (many letterChar) :: Parsec Void String String
editor k = "Key " ++ (fmap toUpper k)
streamEdit key editor "hi <<x>> ! Do you like <<y>>?"
"hi Key X ! Do you like Key Y?"
你也可以用
sepCap
parser combinator,其中 returns 等同于 [Merge]
的结构
您正在尝试构建。