问题很简单:我必须用“xyz”替换所有出现的“fooo”及其所有子串。例如,在Java中,我将这样做:
someString.replaceAll( "fooo|foo|fo", "xyz" )
它会做的伎俩。但在Haskell中,我发现没有有效的方法来使用正则表达式。首先,我读过这个:http://www.haskell.org/haskellwiki/Regular_expressions
实际上具有replace
功能的唯一库是regex-posix,但它在性能上被认为“非常慢”。这个事实是不可接受的。另外我发现这个replace
函数由于任何原因不符合给定模式的顺序,所以我得到这样的输出:
>replace "boo fooo boo" "xyz"
"boo xyzoo boo"
其他后端并不意味着这样的功能。
所以我决定编写简单的解决方法:
replaceFoo input =
helper input []
where
helper ('f':'o':'o':'o':xs) ys = helper xs ("zyx" ++ ys)
helper ('f':'o':'o':xs) ys = helper xs ("zyx" ++ ys)
helper ('f':'o':xs) ys = helper xs ("zyx" ++ ys)
helper (x:xs) ys = helper xs (x:ys)
helper [] ys = reverse ys
虽然我发现这个功能不太好,但效果很好而且速度很快。但是现在我遇到了在这个替换中添加更多单词的必要性,我不喜欢再扩展helper
模式的想法(我需要说实际应用中我实际上有4个单词)单数)。
如果有人帮助我使用快速解决方案,我会很高兴。
cebewee,感谢Data.String.Utils。但我担心如果要替换很多单词(“fooo”到“xyz”,“foo”到“xyz”,“fo”到“xyz”,“bar”到“quux”等等,这种方法很慢),因为为了让它工作,我将需要foldr (\str (from,to) -> replace from to str) input pairs
或类似的东西,它将需要O(n * n)。更重要的是,它可能会取代先前替换结果的子串的意外结果。
答案 0 :(得分:7)
MissingH包中有Data.String.Utils.replace。如果您只需要普通子串替换(而不是正则表达式),那么这可能就是您所需要的。
答案 1 :(得分:4)
regex-xmlschema软件包有一个 sed 函数,可能就是你要找的东西:
http://hackage.haskell.org/package/regex-xmlschema-0.1.3
特别参见:
去年在Haskell-Cafe上讨论了字符串重写的选项:
http://www.haskell.org/pipermail/haskell-cafe/2010-May/077943.html
答案 2 :(得分:0)
通过replace-megaparsec软件包,您可以
搜索模式匹配项,然后编辑找到的匹配项。这是使用的解决方案
Replace.Megaparsec.streamEdit
。
>>> import Replace.Megaparsec
>>> import Text.Megaparsec.Char
>>> streamEdit (chunk "fooo" <|> chunk "foo" <|> chunk "fo") (const "xyz") "boo fooo boo"
"boo xyz boo"