in reply to On the regex pattern variable to be inserted into another

I will confirm the opposite.

If you have variable  $foo= qr/a.*b/ and you plug that into another regex like  my @matches= /$foo/g it will re-compile the regex just to add the /g switch which doesn't even change the content of the regex, and it will re-compile every time it hits that line of code.

I discovered that while writing my Language::FormulaEngine::Parser where I wanted to take author-supplied regexes and then test them against the current position of the input. If you want these to stay pre-compiled, you need to eval the whole sub where they get used and then call that coderef.

Edit: I was wrong, perl does have special cases for  m/$foo/ and  m/$foo/g and  s/$foo/.../ to avoid re-compiling the regex. However, anything more than that like changing the anchor  /\G$foo/gc will trigger a re-compile.

Replies are listed 'Best First'.
Re^2: On the regex pattern variable to be inserted into another
by LanX (Saint) on Feb 10, 2022 at 16:35 UTC
    > /$foo/g

    I expect m/$foo/ to "recompile" because it could also be m/$foo$bar/

    The point of qr is that the inside of $foo=qr// is not effected.

    If you don't want it to be recompiled use $str =~ $foo without surrounding m/.../

    Your problem seems to arise from the /g "global" switch which is actually changing the whole m operator and not the regex.

    Please note that the documentation for qr/STRING/msixpodualn doesn't list /g !

    It might help to know that m// and m//g are realized as separate commands in other languages.°

    update

    °) e.g. in JS

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

      Yes, but it is perfectly reasonable to expect that Perl might recognize  /$foo/ or  /$foo/g as being able to re-use a compiled expression instead of compiling a new one. This is what I think the OP was asking, and I am confirming that no, Perl does not recognize these special cases. The only way to take an unknown regex and efficiently plug it into code that does anything more elaborate than  ... =~ $foo (and gets called more than once, because it will only matter if the code gets called in a loop or something) is to eval an entire sub with the regex expanded within it.
      It might help to know that m// and m//g are realized as separate commands in other languages.

      Yes and in those languages, you can usually create an object to represent the compiled regex and then get either/both operations out of one compilation. Unfortunately perl can't do this easily.

      Edit: Perl does special-case these, actually. Just not anything more elaborate like prefixing  /\G$foo/ to change the anchor.

        > to expect that Perl might recognize /$foo/ or /foo/g as being able to re-use a compiled expression instead of compiling a new one.

        the first case maybe, tho I'm not sure about the implications of having no modifiers outside but inside.

        But how did you prove that /$foo/ is recompiling?

        Anyway as I said $str =~ $foo shouldn't! (untested)

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