尽管Haskell有大量正则表达式匹配的引擎,但我能找到的唯一一个替换的引擎是Text.Regex
,虽然体面,我错过了一些我喜欢的东西。是否有任何基于pcre的软件包可以替代,或者我坚持这个?
答案 0 :(得分:5)
我不会思考"只是滚动自己的"对于那些试图完成实际工作的人来说,这是一个合理的答案,在所有其他现代语言有一个微不足道的方法来实现这一点。包括计划。所以这里有一些实际的资源;我的代码来自一个我试图替换的项目" qql foo bar baz qq"基于在qq"括号"内的东西上调用函数的文本,因为原因。
最佳选择:pcre-heavy:
let newBody = gsub [re|\s(qq[a-z]+)\s(.*?)\sqq\s|] (unWikiReplacer2 titles) body in do
[snip]
unWikiReplacer2 :: [String] -> String -> [String] -> String
unWikiReplacer2 titles match subList = case length subList > 0 of
True -> " --" ++ subList!!1 ++ "-- "
False -> match
请注意,pcre-heavy 直接支持基于功能的替换 字符串类型。太好了。
另一种选择:具有小功能的pcre-light可以工作但不完全正确 高性能:
let newBody = replaceAllPCRE "\\s(qq[a-z]+)\\s(.*?)\\sqq\\s" (unWikiReplacer titles) body in do
[snip]
unWikiReplacer :: [String] -> (PCRE.MatchResult String) -> String
unWikiReplacer titles mr = case length subList > 0 of
True -> " --" ++ subList!!1 ++ "-- "
False -> PCRE.mrMatch mr
where
subList = PCRE.mrSubList mr
-- A very simple, very dumb "replace all instances of this regex
-- with the results of this function" function. Relies on the
-- MatchResult return type.
--
-- https://github.com/erantapaa/haskell-regexp-examples/blob/master/RegexExamples.hs
-- was very helpful to me in constructing this
--
-- I also used
-- https://github.com/jaspervdj/hakyll/blob/ea7d97498275a23fbda06e168904ee261f29594e/src/Hakyll/Core/Util/String.hs
replaceAllPCRE :: String -- ^ Pattern
-> ((PCRE.MatchResult String) -> String) -- ^ Replacement (called on capture)
-> String -- ^ Source string
-> String -- ^ Result
replaceAllPCRE pattern f source =
if (source PCRE.=~ pattern) == True then
replaceAllPCRE pattern f newStr
else
source
where
mr = (source PCRE.=~ pattern)
newStr = (PCRE.mrBefore mr) ++ (f mr) ++ (PCRE.mrAfter mr)
其他人修复:http://0xfe.blogspot.com/2010/09/regex-substitution-in-haskell.html
另一个,这次嵌入在一个主要的库中:https://github.com/jaspervdj/hakyll/blob/master/src/Hakyll/Core/Util/String.hs
答案 1 :(得分:3)
regex-base中的正则表达式API对于要匹配的字符容器是通用的。一般地进行某种拼接以实现替换将非常难以提高效率。我不想提供一个糟糕的通用例程。
编写一个小函数来完全按照你想要的方式进行替换只是一个更好的主意,并且可以编写它来匹配你的容器。
答案 2 :(得分:2)
我完全同意@rlpowell的观点
在所有其他现代语言都有琐碎的方法来完成这一工作的领域,我不认为“自己动手做”是对试图完成实际工作的人们的合理答案。
在撰写本文时,尽管与Perl不兼容,但也有Regex.Applicative.replace
可以用于正则表达式替换。
对于模式匹配和解析器而不是正则表达式的替换,有Replace.Megaparsec.streamEdit