How to reference captured groups in the replacement? #2

Open
opened 2023-05-09 03:48:08 +02:00 by halloleo · 3 comments
Contributor

I try t use a captured group in the repalcement. For example

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes, FlexibleContexts #-}

import Text.Regex.PCRE.Heavy as RE

cleanMe  :: Text -> Text
cleanMe txt = RE.gsub [re|^([0-9]*)DELETABLE-NUMMARKER]  "\1NEW-NUMMARKER" txt

But this does not the work. the only way I made it works is the cumbdersome function approach:

cleanMe txt = RE.gsub [re|^(.*)DELETABLE-MARKER]  (\(g1:_) -> g1 ++ "NEW-NUMMARKER") txt

How can I reference the captures group directly in the replacement argument?

I try t use a captured group in the repalcement. For example ``` {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE QuasiQuotes, FlexibleContexts #-} import Text.Regex.PCRE.Heavy as RE cleanMe :: Text -> Text cleanMe txt = RE.gsub [re|^([0-9]*)DELETABLE-NUMMARKER] "\1NEW-NUMMARKER" txt ``` But this does not the work. the only way I made it works is the cumbdersome function approach: ``` cleanMe txt = RE.gsub [re|^(.*)DELETABLE-MARKER] (\(g1:_) -> g1 ++ "NEW-NUMMARKER") txt ``` How can I reference the captures group directly in the replacement argument?
halloleo changed title from How to add caltured groups in teh repalve,ent? to How to reference captured groups in the replacement? 2023-05-09 03:48:45 +02:00
Owner

Yes, you can only do it with functions. I haven't found it to be cumbersome and I rather like not having another stringy syntax.

I guess it would be nice to have a TH thingy that would compile e.g. [rep|\1NEW-NUMMARKER|] to (\(g1:_) -> g1 ++ "NEW-NUMMARKER"). PRs welcome :)

Yes, you can only do it with functions. I haven't found it to be cumbersome and I rather like not having another stringy syntax. I guess it would be nice to have a TH thingy that would compile e.g. `[rep|\1NEW-NUMMARKER|]` to `(\(g1:_) -> g1 ++ "NEW-NUMMARKER")`. PRs welcome :)
Author
Contributor

Thanks for the clarification!

Using a function is not too bad, but I always get these "Pattern match(es) are non-exhaustive In a lambda abstraction" warning on that function, which is annoying...

I am just starting out with Haskell, so I don't think I can write appropriate code (yet), but I certainly can update the documentation to make it clearer that functions are the only way to get captured groups into the replacement.

Thanks for the clarification! Using a function is not *too* bad, but I always get these "_Pattern match(es) are non-exhaustive In a lambda abstraction_" warning on that function, which is annoying... I am just starting out with Haskell, so I don't think I can write appropriate code (yet), but I certainly can update the documentation to make it clearer that functions are the _only_ way to get captured groups into the replacement.

Using a function is not too bad, but I always get these "Pattern match(es) are non-exhaustive In a lambda abstraction" warning on that function, which is annoying...

FYI, you could also write your example like

cleanMe txt = RE.gsub [re|^(.*)DELETABLE-MARKER] replace txt
  where
    replace :: [String] -> String
    replace [g1] = g1 <> "NEW-NUMMARKER"
    replace _ = error "replace function received the wrong number of arguments"

This still has the underlying problem that you were getting the warning about—that your replacement function is expecting a list with exactly one element, and that it will crash if it gets a different number of elements—but it’s more explicit about this failure case (because of the explicit use of error) and it should also suppress that warning.

> Using a function is not too bad, but I always get these "Pattern match(es) are non-exhaustive In a lambda abstraction" warning on that function, which is annoying... FYI, you could also write your example like ```haskell cleanMe txt = RE.gsub [re|^(.*)DELETABLE-MARKER] replace txt where replace :: [String] -> String replace [g1] = g1 <> "NEW-NUMMARKER" replace _ = error "replace function received the wrong number of arguments" ``` This still has the underlying problem that you were getting the warning about—that your replacement function is expecting a list with exactly one element, and that it will crash if it gets a different number of elements—but it’s more explicit about this failure case (because of the explicit use of `error`) and it should also suppress that warning.
Sign in to join this conversation.
No labels
No milestone
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
valpackett/pcre-heavy#2
No description provided.