Best way to replace substring in haskell

The problem is quite simple: I need to replace all occurrences of "fooo" and all its substrings with "xyz". In Java, for example, I will do it as follows:

someString.replaceAll( "fooo|foo|fo", "xyz" ) 

and that will do the trick. But in Haskell, I did not find an effective way to work with regex. First of all, I read the following: http://www.haskell.org/haskellwiki/Regular_expressions

The only library that actually has a replace function is regex-posix, but it is considered "very slow" in performance. And this fact is unacceptable. I also found that this replace function for some reason does not take into account the order of the given patterns, so I got the result as follows:

 >replace "boo fooo boo" "xyz" "boo xyzoo boo" 

Other backends do not imply such functionality.

So, I decided to write a simple way:

 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 

While I do not find this feature pleasant, it works well and quickly. But at the moment, I met the need to add more words to this substitute, and I do not like the idea of ​​expanding helper templates more (I have to say that I actually have 4 words in a real application and this is odd).

I will be glad if someone helps me with a quick solution.


cebewee , thanks for Data.String.Utils. But I'm afraid that this approach is rather slow if you replace a lot of words ("fooo" with "xyz", "foo" with "xyz", "fo" with "xyz", "bar" with "quux", etc. .), because for this I will need foldr (\str (from,to) -> replace from to str) input pairs or something like that, and it will take O (n * n). Moreover, this may have the unexpected result of replacing a substring of the result of a previous replacement.

+7
substring replace haskell
source share
3 answers

The regex-xmlschema package has a sed function, which may be what you are looking for:

http://hackage.haskell.org/package/regex-xmlschema-0.1.3

See in particular:

http://hackage.haskell.org/packages/archive/regex-xmlschema/0.1.3/doc/html/Text-Regex-XMLSchema-String.html#v:sed

Last year, options for rewriting strings in Haskell-Cafe were discussed:

http://www.haskell.org/pipermail/haskell-cafe/2010-May/077943.html

+4
source share

The MissingH package has Data.String.Utils.replace . If you need a simple substring replacement (rather than regular expressions), this may be what you need.

+7
source share

The replace-megaparsec package allows you to search for matches with a pattern and then edit the matches found. Here is a solution using 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" 
0
source share

All Articles