Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re^2: Regexp substitution using variables

by MikeTaylor (Acolyte)
on Nov 25, 2020 at 22:24 UTC ( [id://11124231]=note: print w/replies, xml ) Need Help??


in reply to Re: Regexp substitution using variables
in thread Regexp substitution using variables

Thank you to all of you who have suggested the form s/(?$flags:$pattern)/$replacement/. I think this will get me much of what I need. The fact that the global-replace flag "g" doesn't work in this position is an annoying wrinkle, but I am going to take a deep breath and code up the with-g and without-g cases separately, depending on whether or not $flags =~ s/g// succeeds.
  • Comment on Re^2: Regexp substitution using variables

Replies are listed 'Best First'.
Re^3: Regexp substitution using variables
by LanX (Saint) on Nov 26, 2020 at 00:40 UTC
    > with-g and without-g cases separately, depending on whether or not $flags =~ s/g// succeeds.

    That's reasonable, because /g is not a simple modifier changing the match-rules, it turns the "replace" into a different "replace_all" command with very different behavior.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Re^3: Regexp substitution using variables
by bart (Canon) on Nov 28, 2020 at 11:49 UTC
    but I am going to take a deep breath and code up the with-g and without-g cases separately
    What is the obsession of people to try and solve a complex problem like this in a single line of code, just because it can be done in one line of code in a perl script? I don't mean you specifically, but in general, like apparently most people who replied to this thread.

    Splitting this up in two parts makes sense, using /g is not a modifier of the pattern (as it is in several other languages), but of the substitution. Something like this looks acceptable to me as the (obvious) redundancy is actually quite limited:

    if($flages =~ s/g//) { s/(?:$flags)$pattern/replacement($replacement)/ge; } else { s/(?:$flags)$pattern/replacement($replacement)/e; }
    where you still have to provide the sub replacement.

    Other flags cannot really coded this way, but there's no need to provide for /o or /r at all, and allowing people to use /e flag in a config file, simply looks dangerous to me. If people would really want to use /e, it likely would be for just a handful of specific cases, and you can instead code a simpler solution for those cases (for the user, not necessarily for you) explicitly in your script, than having them write convoluted perl code.

    That real danger of allowing ordinary users to run arbitrary code, is also why I really don't like use of eval. It also enforces taking special care to be taken when writing the sub replacement. You can mitigate the danger by using a module like String::Interpolate, to embed captured values while disallowing access to the rest of the intestines of the script. .

Re^3: Regexp substitution using variables
by MikeTaylor (Acolyte) on Nov 25, 2020 at 22:36 UTC
    Well, this gets me much of what I need ... but I can't get back-references, either with $1 or \1. In either case, they appear as literals. Any ideas, other than eval?
      > but I can't get back-references,

      This works for me

      DB<44> $pat='(x)\1' DB<45> $mod='i' DB<46> 'xX' =~ /(?$mod)$pat/; say "$&:$1" xX:x DB<47>

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        Sorry, I think I was using the term "back-reference" incorrectly. I didn't mean referring back within the pattern to something earlier in the pattern, but referring in the substitution string to a captured sub-expression of the pattern. Something like s/(foo|bar)/He said "$1"/.
Re^3: Regexp substitution using variables
by Bod (Parson) on Nov 25, 2020 at 22:32 UTC

    depending on whether or not $flags =~ s/g// succeeds

    Testing $flags =~ /g/; is simpler.

      Simpler, but doesn't quite do what I need. I want to supply the remaining flags, once g has been removed, in the (?$flags:...) part of the expression. And I need to remove the g so that I don't get flooded with noisy console warnings about how it's being ignored.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11124231]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2024-03-29 15:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found