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

Regular Expression problem with $variable =~ m/C++/

by Manlio (Novice)
on Jun 11, 2007 at 14:35 UTC ( #620500=perlquestion: print w/replies, xml ) Need Help??

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

Hi to everybody,
Often I need to read a CSV file with delimited by commas. In order to find more quickly the value of a variable, inside the lines I use the matching regular expression $variable =~ m/.../.
Today I read a file with the 'C++' string inside (Only later I have understood that responsibility was of the 'C++' string).
The script has stopped with the following error message:

Nested quantifiers in regex; marked by <-- HERE in m/C++ <-- HERE / at....

So I have created a dedicated test script in order to verify the problem:
use strict; #looked variable my $VarString = 'C++'; my $Counter = 0; #example array (it simulates the file lines) my @Array; #push variable (CSV delimited) in array $Array[0] = 'VISUAL BASIC,PERL,PASCAL'; $Array[1] = 'C#,C,C++'; $Array[2] = 'ASSEMBLER,PHP,JAVA'; $Array[3] = 'HTML,XML,JAVA'; print "Start...\n"; #search string in array while ($Counter <= $#Array){ #check with the matching expression next unless $Array[$Counter] =~ m/$VarString/; print "I have found the string $VarString in array position $Count +er!\n"; }continue{ #increment the array position $Counter++; } print "Stop\n";
In this code if the $VarString (string looked for) is 'PHP' (for example) it's all okay, but if you set 'C++' the problem arrives. Because the characters '++' they are considered inside of the match pattern.

Thanks for all the suggestions! M.

Replies are listed 'Best First'.
Re: Regular Expression problem with $variable =~ m/C++/
by ikegami (Pope) on Jun 11, 2007 at 14:50 UTC
    The argument of the match operator (m//) is a regexp, not arbitrary text. An easy way to convert arbitrary text into a regular expressions in to use quotemeta.
    my $re = quotemeta($VarString); next unless $Array[$Counter] =~ m/$re/;

    Another trick is to use \Q...\E.

    next unless $Array[$Counter] =~ m/\Q$VarString\E/;

    By the way, do realize that if $VarString = 'C';, (poorly named) $Array[0] would match because there's a C in VISUAL BASIC? You also have problems with $VarString = 'VB'; (doesn't exist) and $VarString = 'Perl'; (case issue)

      Thank you, 'quotemeta' is a very good solution. I have also tried already the use of \Q...\E.

      You are right when you speak (for example) about 'c' letter in Visual Basic. Fortunately I have to compare always complex names that are never included in other name.
      Thank you for your support!
        You might find the following useful:
        my @matches = grep { ",$Array[$_]," =~ /,\Q$VarString\E,/i } 0..$#Arra +y;

        @matches will contain the indexes (0, 1, 2 and/or 3) or the elements of @Array that contains the matching substrings. The commas ensure C won't match VISUAL BASIC, and the i ensures Perl will match PERL.

        If the same item won't appear in two array elements, then you can use the following version to store the index in $match:

        my ($match) = grep { ",$Array[$_]," =~ /,\Q$VarString\E,/i } 0..$#Arra +y;
Re: Regular Expression problem with $variable =~ m/C++/
by ForgotPasswordAgain (Priest) on Jun 11, 2007 at 14:38 UTC
    You want to look at `perldoc perlre` and search for 'quotemeta', since '+' is obviously a special character in regexes.
      Thanks! I will go to read the relative documentations. Kind regards, M.
Re: Regular Expression problem with $variable =~ m/C++/
by varian (Chaplain) on Jun 11, 2007 at 14:48 UTC
    If your merely want to search for string literals inside a line then the index function is fast, does not interprete metacharacters and will do just fine:
    next unless index($Array[$Counter],$VarString) >= 0;
      Good idea! Thank you!
Re: Regular Expression problem with $variable =~ m/C++/
by GrandFather (Saint) on Jun 11, 2007 at 19:34 UTC

    Your sample could perhaps be better written using a __DATA__ section as:

    use strict; #looked variable my $VarString = 'C++'; print "Start...\n"; #search string while (<DATA>) { #check with the matching expression next unless m/$VarString/; chomp; print "I have found the string $VarString at line $.\n"; } print "Stop\n"; __DATA__ VISUAL BASIC,PERL,PASCAL C#,C,C++ ASSEMBLER,PHP,JAVA HTML,XML,JAVA

    but the major issue is the old problem of reinventing tricky wheels. CSV, in general, is tricky to parse correctly. You are much better to use something like Text::CSV.

    DWIM is Perl's answer to Gödel
      Thank you for your suggestion!

      I would like to use very powerful module (that I have seen), but my Server Provider doesn't want to install any CPAN module, not included in the default Perl installation!! ;-(

      In fact I will open another discussion about this problem.

      "How is possible to use the CPAN module in local folder without installation in the Perl folder?"

      If I copy the module in my folder on the Server (where there are my scripts), can I call it as if they was included in the Perl folder?

      I would like to modify the call of the module (for example Text::CSV):
      use Text::CSV;
      with something like this:
      require '.../Text::CSV';
      (Like function library)

      In this way I could use all the module that I need, even if they are not installed inside the Perl folder.
      I have already made some tests but unfortunately with any positive result...
        You need to find your directory then point the LIB environment variable to it, or a subdirectory, as in this snippet:
        use FindBin; use lib "$FindBin::Bin/lib";

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://620500]
Approved by Corion
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (5)
As of 2021-10-23 09:14 GMT
Find Nodes?
    Voting Booth?
    My first memorable Perl project was:

    Results (88 votes). Check out past polls.