简体   繁体   中英

Replace regex match by arbitrary function of match itself

I'm trying to write a function of type Text -> (Text -> Text) -> Text that replaces occurrences of a regular expression in a piece of text by something else that is a function of what the regular expression has matched. There is subRegex from Text.Regex but this only allows replacing a match with some fixed replacement string whereas I would like the replacement to an an arbitrary function of the match. Is there a package that already implements something like that?

You can use 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 )

For example:

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

If you want to do this for all matches rather than just the first, you can call this function recursively on the remainder post (left as an exercise).

For a different approach, it looks like the text-regex-replace replace package might be of use to you. It works directly on Text rather than String , and it appears to have the capability of arbitrary replacement functions (however the usage seems a bit obtuse).

If you're willing to write your pattern matching function as a parser instead of a regular expression, then the function Replace.Megaparsec.streamEdit with the match combinator has the signature you're looking for.

Here's a usage example in the README

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM