http://www.perlmonks.org?node_id=822989

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

I can seem to figure out why this isn't matching. I can only figure it has something to do with the square brackets.

How can I get this to work?
#!/usr/bin/perl -w use strict; use Data::Dumper; my $orig = 'my_stuff[1]=400'; my $want = 'my_stuff[1]='; print "They Match\n" if $orig =~ /$want/;

Replies are listed 'Best First'.
Re: How does this regex not match?
by CountZero (Bishop) on Feb 13, 2010 at 09:11 UTC
    $orig =~ /\Q$want\E/;
    will match. You must quote your string if it contains any special characters, such as [ and ], unless of course you want these characters to retain their special meaning.

    Please note that whatever is put between \Q and \E undergoes variable interpolation first.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: How does this regex not match?
by Anonymous Monk on Feb 13, 2010 at 07:47 UTC
    Basic regex syntax, brackets create a character class
    use re 'debug'; my $orig = 'my_stuff[1]=400'; my $want = 'my_stuff[1]='; print "They Match\n" if $orig =~ /$want/; __END__ Compiling REx "my_stuff[1]=" Final program: 1: EXACT <my_stuff1=> (8) 8: END (0) anchored "my_stuff1=" at 0 (checking anchored isall) minlen 10 Guessing start of match in sv for REx "my_stuff[1]=" against "my_stuff +[1]=400" Did not find anchored substr "my_stuff1="... Match rejected by optimizer Freeing REx: "my_stuff[1]="
    you want /\Q$want\E/ or substr
      not substr, but eq or index
Re: How does this regex not match?
by 7stud (Deacon) on Feb 13, 2010 at 11:54 UTC

    If you are having trouble figuring out what the previous responses are saying, the regex my_stuff[1] is equivalent to the regex my_stuff1, which does not appear in your original string.

    The regex my_stuff[1] says to look for the string 'my_stuff' followed by one of the characters specified in the brackets. Because you only have one character specified in the brackets, the regex is equivalent to mystuff1.

    Here is an example of how brackets can prove useful in a regex:

    use strict; use warnings; use 5.010; my $pattern = 'x[ABC]'; my @strings = ( 'xA', 'xB', 'xC', 'xY', ); for (@strings) { if (/$pattern/) { say; } } --output:-- xA xB xC

    In order to literally match any of the regex characters that have special meaning (e.g. * . ?), you have to 'escape' the character. You 'escape' a special character with a '\', which tells perl to ignore the special regex meaning of the character. As it turns out, you only have to escape the opening bracket, and then perl knows the closing bracket is to be interpreted as a literal bracket:

    use strict; use warnings; use 5.010; my $string= 'my_stuff[1]=400'; my $pattern = 'my_stuff\[1]='; say "They match." if $string =~ /$pattern/; --output:-- They match.
Re: How does this regex not match?
by targetsmart (Curate) on Feb 13, 2010 at 14:22 UTC
    quotemeta the pattern variable and use it to match with the string
    (will work for your case)

    perl -ne "$var = quotemeta('my_stuff[1]=400'); print if /$var/ "


    Vivek
    -- 'I' am not the body, 'I' am the 'soul/consciousness', which has no beginning or no end, no attachment or no aversion, nothing to attain or lose.

      I am informed by /msg from targetsmart that the example code in Re: How does this regex not match? works in Perl 5.6.1, Windows XP, to demonstrate the operation of quotemeta. I cannot see how, but I cannot test it in 5.6.1 (or even 5.8.x at the moment). It does not work in Strawberry 5.10.1.0, Windows 7.

      The following example code works to demonstrate  quotemeta in Strawberry 5.10.1.0:

      >perl -wMstrict -le "my $var = quotemeta 'my_stuff[1]'; print 'match' if 'my_stuff[1]=400' =~ /$var/; " match
Re: How does this regex not match?
by FunkyMonk (Chancellor) on Feb 13, 2010 at 14:26 UTC
    Or, you could use the quotemeta function that does exactly the same as \Q...\E quoted above:

    my $want = quotemeta 'my_stuff[1]=';
Re: How does this regex not match?
by repellent (Priest) on Feb 13, 2010 at 18:29 UTC
    Don't use regex, use index.
    print "They Match\n" if index($orig, $want) >= 0;