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


in reply to regex match with interpolated pattern

You're date variable is using / as the delimiter. As a result you aren't matching the pattern you think you are. You could just use a different delimiter for your pattern.
if ($_ = m%$dm%) { #stuff }
Or you could call quotemeta() on your variable.
my $dm = quotemeta($date);
quotemeta() will escape all non-word characters.

UPDATE: After reading hv's reply, I agree with him. SOmething didn't seem right to me as I was replying...he caught it though :)


dsb
This @ISA my cool %SIG

Replies are listed 'Best First'.
Re^2: regex match with interpolated pattern
by fletcher_the_dog (Friar) on Aug 18, 2004 at 19:49 UTC
    You're date variable is using / as the delimiter. As a result you aren't matching the pattern you think you are. You could just use a different delimiter for your pattern.
    if ($_ = m%$dm%) { #stuff }
    If you are interpolating a string it does not matter if it has characters that are the same as the delimiter. The boundaries of the regex are determined before the interpolation is done. Try this:
    perl -e '$string = "/"; print "08/14/04"=~/$string/ ? "matched\n" : "no match\n"'
Re^2: regex match with interpolated pattern
by drock (Beadle) on Aug 18, 2004 at 15:45 UTC
    ok men, I tried all 3 suggestions and none worked so here is my code. Again $dm and $dmm are dereived from the subroutines are are in format xx/xx/xx
    sub date_manip { my ($month, $day, $year) = (localtime)[4,3,5]; sprintf ("%02d/%02d/%02d\n", $month+1,$day,($year % 10 +0)); } my $dm = '&date_manip'; sub date_manip1 { my $days = (shift); my ($d, $m, $y) = (localtime($time - $days * 86400)) [ +3..5]; sprintf ("%02d/%02d/%02d", $m+1,$d,($y % 100)); } my $dmm = '&date_manip1(1)'; #print ("$dm $dmm"); ############################################################ ## Gather data for scratch tapes; open file, create list, then print i +t. ## ############################################################ open (FOO, ">$scratches") || die "could not open file:$!"; #($^I, @ARGV) = ('.bak', $scratches); open (D, "$logf") || die "could not open file:$!"; while (<D>) { ## look for 9840S and ebexpire ## declare OFS = tab ## tell split to split on IRS 0,1&5. # if (($_ =~ /9840S/) && ($_ =~ /ebexpire, ebexpire/ ) +) { if (($_ =~ /9840S/) && ($_ =~ /ebexpire, ebexpire/ ) & +& ( $_ =~ m/$dm/) && ($_ =~ m/$dmm/)) { local $, = "\t"; print FOO +(split)[0,1,5], $/ ; } } close (FOO); close (D);
      This code works (that is, the print executes) for me, and should work for you:
      $dm='08/14/04'; $_='There is an 08/14/04 in here'; if ($_ =~ m/$dm/) { print "Matched on <$_>\n"; }
      The code you've included so far hasn't been the kind of test code we'd most like to see, which is an actual program that we can run that demonstrates the problem.

      In this last excerpt, you're quoting your subroutine calls, which results in the subroutines not being called. Also, you're putting a newline in your date_manip, which may not be what you want. Here's a test-code modification that may help you out:

      #!perl sub date_manip { my ($month, $day, $year) = (localtime)[4,3,5]; sprintf ("%02d/%02d/%02d\n", $month+1,$day,($year % 100)); } my $dm = &date_manip; sub date_manip1 { my $days = (shift); my ($d, $m, $y) = (localtime($time - $days * 86400)) [3..5]; sprintf ("%02d/%02d/%02d", $m+1,$d,($y % 100)); } my $dmm = &date_manip1(1); print ("{$dm} {$dmm}\n"); ############################################################ ## Gather data for scratch tapes; open file, create list, then print i +t. ## ############################################################ while (<DATA>) { print "-- Checking <$_>\n"; print "Found 9840\n" if /9840S/; print "Found ebexpire\n" if /ebexpire, ebexpire/; print "Found $dm\n" if /$dm/; print "Found $dmm\n" if /$dmm/; } __DATA__ 9840S ebexpire, ebexpire 12/30/69 08/18/04 9840S ebexpire, ebeXpire 12/30/69 08/18/04 9840S ebexpire, ebexpire XX/30/69 08/18/04

      Caution: Contents may have been coded under pressure.

      Uncomment your print ("$dm $dmm");. You'll see that you actually have the literal strings '&date_manip' and '&date_manip1(1)' in them. That's why they're not matching something that looks like a date.

      Just use:

      $dm = date_manip(); $dmm = date_manip1(1);

      And you'll be a lot closer.

      You also may wish to check out Date::Calc and Date::Manip and choose one for your date routines.