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.