Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Using constants in regexes?

by Kozz (Friar)
on Aug 11, 2001 at 02:31 UTC ( [id://104059]=perlquestion: print w/replies, xml ) Need Help??

Kozz has asked for the wisdom of the Perl Monks concerning the following question: (regular expressions)

If I were to create something like
use constant TEST => 'def'; my $string = 'abcdefg'; if ($string =~ /TEST/) { print "The string contains the constant.\n"; }else{ print "The string doesn't contain the constant.\n"; }
It's awfully hard for the interpreter to know that TEST is actually a constant, because to the regex engine it's just another string. The /e modifier doesn't work. Is there a way to do this?

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: Using CODEconstant/CODEs in regexes?
by japhy (Canon) on Aug 11, 2001 at 02:54 UTC
    The /e modifier is for the right-hand side of a s/// only. You might want to just leave out the slashes.
    use constant PATTERN => qr/def/; if ($string =~ PATTERN) { ... }
    Or, if you need to embed a constant, use the array dereference-reference trick:
    if ($string =~ /this@{[ PATTERN ]}that/) { ... }
Re: Using CODEconstant/CODEs in regexes?
by abstracts (Hermit) on Aug 11, 2001 at 02:52 UTC
    Use the (?{ CODE }) experimental feature at your own risk:
    use constant TEST => 'def'; my $string = 'abcdefg'; if ($string =~ /(?{TEST})/) { print "The string contains the constant.\n"; }else{ print "The string doesn't contain the constant.\n"; }

    Aziz,,,

      Err, I think you were thinking of (??{ ... }). That's overkill, in my opinion. Your approach doesn't work, since (?{ ... }) merely executes code, it doesn't use it as part of the regex.

      _____________________________________________________
      Jeff[japhy]Pinyan: Perl, regex, and perl hacker.
      s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

        You are absolutely right: it was $$ not $. And yes it is an overkill, but it works. I just couldn't remember the syntax of @{[...]}.

        Thanks for the correction

        Aziz,,,

Re: Using constants in regexes?
by dclayton (Initiate) on Feb 01, 2005 at 20:13 UTC
    There's a few ways of tackling this problem, depending on your goals. To use a constant as an interpolated value within a regular expression, use the following notation:
    if ($string =~ /${\(TEST)}/) {
    This has the unfortunate consequence of slowing down your regular expression, since it can't be compiled. Using the qr operator is your best bet. You can use japhy's suggested format:
    use constant PATTERN => qr/def/; if ($string =~ PATTERN) { ... }
    An alternative is to leave the constant in string format, and compile it just prior to executing the regex:
    use constant PATTERN => 'def'; my $regex = qr/${\(PATTERN)}/; #options such as /m can go here. if ($string =~ regex) { ... }
    This gives you the added benefit of being able to easily print the regex out for debugging purposes.

      Your statements about the middle example are the only correct thing in your post. In your example /${\(TEST)}/ you state that it can't be compiled. This is false. First time this expression is executed the string form of it is compiled. Since the string form will never change, the compiled expression is retained for the life of the process. You do still incur a runtime hit of evaluating ${\TEST} each time but that is not comparable with the regex compilation cost. That recurring cost can be removed by appending the /o flag which informs the interpreter to never attempt to evaluate the string again. So /${\TEST}/o is perfectly fine and imposes no performance penalty.

      Your last example uses the same logic I just described for the first example. The ${\PATTERN} string is still evaluated every time except this time you never have the option to use the /o parameter.

Re: Using constants in regexes?
by freonpsandoz (Beadle) on Sep 08, 2015 at 09:23 UTC
    I'm not sure using qr is the best advice. This fuses what the constant *represents* with just one potential use of that constant, which will lead to problems maintaining the code, because using that constant for anything else (like print or eq) will give incorrect results. Most of these incorrect uses don't even give a compile error; they just produce incorrect results.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2024-04-19 22:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found