【发布时间】:2021-01-03 11:35:48
【问题描述】:
我正在尝试编写一个Text -> (Text -> Text) -> Text 类型的函数,它将一段文本中出现的正则表达式替换为正则表达式匹配的函数。 Text.Regex 中有 subRegex 但这仅允许用一些固定的替换字符串替换匹配项,而我希望替换为匹配项的任意函数。是否有一个包已经实现了类似的东西?
【问题讨论】:
我正在尝试编写一个Text -> (Text -> Text) -> Text 类型的函数,它将一段文本中出现的正则表达式替换为正则表达式匹配的函数。 Text.Regex 中有 subRegex 但这仅允许用一些固定的替换字符串替换匹配项,而我希望替换为匹配项的任意函数。是否有一个包已经实现了类似的东西?
【问题讨论】:
您可以使用matchRegexAll
matchRegexAll
:: Regex -- ^ The regular expression
-> String -- ^ The string to match against
-> Maybe ( String, String, String, [String] )
-- ^ Returns: 'Nothing' if the match failed, or:
--
-- > Just ( everything before match,
-- > portion matched,
-- > everything after the match,
-- > subexpression matches )
例如:
subFirst :: Regex -> String -> (String -> String) -> String
subFirst rx input f = case matchRegexAll rx input of
Nothing -> input
Just (pre, match, post, _) -> pre <> f match <> post
如果您想对所有匹配项而不是第一个匹配项执行此操作,您可以在余数 post 上递归调用此函数(留作练习)。
对于不同的方法,看起来text-regex-replace replace 包可能对您有用。它直接作用于Text 而不是String,而且它似乎具有任意替换函数的能力(不过用法似乎有点迟钝)。
【讨论】:
如果您愿意将模式匹配函数编写为解析器而不是正则表达式,那么带有 match 组合子的函数 Replace.Megaparsec.streamEdit 具有您正在寻找的签名。
【讨论】: