doing trivial search and replace via a regex

I am using regex-tdfa which installs easiely with stack

As seen in the docs, using a regex predicate is simple:

λ> emailRegex = "[a-zA-Z0-9+._-]+@[a-zA-Z-]+\\.[a-z]+"
λ> "my email is email@email.com" =~ emailRegex :: Bool

How can I search and replace with this lib ? I would like for example, to filter out characters from a string.

I can't fmap on a string with the =~operator since it expects strings and not characters as input, which is why I am stuck.

Many thanks.

1 answer

  • answered 2019-06-24 22:37 K. A. Buhr

    You can use the (=~) form that returns the "before", "matched", and "after" parts. To replace only the first occurrence, use:

    replace1 :: String -> String -> String -> String
    replace1 pat repl str
      = let (a,b,c) = str =~ pat :: (String, String, String)
        in  a ++ repl ++ c
    

    To replace all non-overlapping occurrences, use a recursive solution.

    replace :: String -> String -> String -> String
    replace pat repl str
      = case str =~ pat :: (String, String, String) of
          (rest, "", "") -> rest
          (a, b, c) -> a ++ repl ++ replace pat repl c
    

    If you want something fancier than fixed-text replacement, you can change the type of repl from String to String -> String in the obvious way, or use the "get first match and submatches" form, if you also want repl :: String -> [String] -> String to act on the submatches.

    Of course, if you really want to "filter out characters from a string", then a better solution is:

    filter (not . isDigit) "N0 0ne 7ike5 num83r5"