barryscott has asked for the wisdom of the Perl Monks concerning the following question:

I need to check a string to see if it contains one of a number of sub strings. Rather than do something like
if ($string =~ /int/) ... elsif ($string =~ /char/) ... elsif ($string =~ /bool/) ... elsif ($string =~ /long/) ...
is there a way of doing something like
if ($string =~ /(int)|(char)|(bool)|(long)/){ #my single action... }
Please forgive my poor, c style attempt at a construct...

Replies are listed 'Best First'.
Re: multiple options for pattern match help
by lima1 (Curate) on Jan 08, 2008 at 15:37 UTC
    if ($string =~ m{(int|char|bool|long)}) { print "found $1\n"; }
    If you don't need to know which type matched, use
    if ($string =~ m{(?:int|char|bool|long)}) { print "found\n"; }
    This can be significantly faster, especially for big strings. Update: Thanks sundialsvc4 :).

      To clarify what is meant here:   in the regular expression syntax, parentheses normally imply grouping in the sense that you can subsequently extract the substring that matched that particular group. In the case at bar, if the result is True, the special-variable $1 will contain what matched the first group, $2 the second group (if any), and so on. So, $1 would contain one of: int, char, bool, long.

      If you don't need to know what matched, the ?: construct tells the regular-expression parser that you're using the parentheses only to express a set of alternatives; that you don't need to subsequently use $1 and so-on. So, Perl won't bother to populate those variables (at least for that group...), and this saves time. You'll know whether or not the expression matched, but you won't know exactly what matched that group.

Re: multiple options for pattern match help
by Corion (Patriarch) on Jan 08, 2008 at 15:27 UTC

    What was the error message when you tried your code?

    Also see perlre

Re: multiple options for pattern match help
by svenXY (Deacon) on Jan 08, 2008 at 15:32 UTC
    Hi,
    what's wrong wioth your code? Works fine for me:
    my $string = 'somechar acters'; if ($string =~ /(int)|(char)|(bool)|(long)/){ print "matches\n"; }
    prints
    matches

    It can become quite confusing if you test for a lot of strings in one regex, then I'd go for a lookup array or even better a hash.
    Regards,
    svenXY
Re: multiple options for pattern match help
by poolpi (Hermit) on Jan 08, 2008 at 15:46 UTC
    Try this,
    my $regexp = qr/ (?: ( int | char | bool | long ) ) /x; if ($string =~ /\A $regexp \z/xms){ print $&, "\n"; }

    PooLpi
    Update : Parenthesis, thanks lima1 ;)
      my $regexp = qr/ (?: ( int | char | bool | long ) ) /x;
      There's still the grouping parentheses. It should be like this in order to follow lima1's update:
      my $regexp = qr/ (?: int | char | bool | long ) /x;