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

i am getting this error: search pattern not terminated...what could be the problem. I am trying to parse the apache access log:

eg of an entry:

10.25.95.100 ab - [05/Aug/2003:12:00:30 -0700] "GET /creative/2|212727 +4-1;iframe? HTTP/1.1" 200 791
My code:
#!/usr/bin/perl -w use strict; my $s = '10.25.95.100 ab - [05/Aug/2003:12:00:30 -0700] "GET /creative +/2|2127274-1;iframe? HTTP/1.1" 200 791 "-" "Mozilla/4.0(compatible; M +SIE 5.5; Windows 98)""TC1=1067055_5565+067055+0+30fc+3fb5+20742d+1; P +WH=m2w/./o0.Nyvo0/I..d/I./I.; Xc294&2127030&1=1059866137&13384&18337; + Xc15&2127102&2=1060109088&13025&17516; Xc200&2127519&2=1060109135&13 +301&18215" "Imp: 294&18421&2127274&1&13384&1060110030" -'; my $LOG_PATTERN = q{(.*) \- \[(.*)\] \"(.*) (.*)\?(.*) HTTP\/(.*)\" ([ +0-9]*) ([0-9]*)}; print "\$s=$s\n"; my $var10=''; $s =~ /(.*) \- \[(.*)\] \"(.*) (.*)\?(.*) HTTP\/(.*)\" ([0-9]*) ([0-9] +*) \"(.*)\" \"(.*)\"/; print "Trick 1: \$1=$1, \$2=$2, \$3=$3, \$4=$4, \$5=$5, \$6=$6, \$7=$7 +, \$8=$8, \$9=$9, \n", " \$\`=",$`," \$\'=",$',"\n"; my $len = @ARGV; if ($len <1){ print "Usage : perl script_name logfile\n"; exit(); } if (!(-e $ARGV[0])){ print $ARGV[0]," : not exists.\n"; exit(); } open (SEM, "< $ARGV[0]") or die "Cannot open file $ARGV[0]\n"; while () { if (my($ip,$date,$method,$url,$query,$protocol,$retcode,$byte)=($_ =~ +m/$LOG_PATTERN)) { print "IP :",$ip,"\n";} } close(SEM);
when I try to add a trailing /, I get the warning: Use of uninitialized value in pattern match (m//) at learn1.plx line 42

Replies are listed 'Best First'.
Re: search pattern not terminated
by GrandFather (Saint) on Jan 21, 2008 at 23:59 UTC

    It may be the missing '/' in:

    ($_ =~ m/$LOG_PATTERN))

    Perl is environmentally friendly - it saves trees
      thanks for your assistance. when i palce a trailing / I get the warning: Use of uninitialized value in pattern match (m//) at learn1.plx line 42
      Where should i be placing the trailing/ ?

        Where did the code come from? I presume (given the level of your questions) that this is not your own code. There are some rather unusual aspects to the code and if you are not a reasonably competent Perl programmer I suspect you will continue to have trouble with it.

        For a start while () {...} is an unterminated loop, which is unlikely to be correct given that there is code following it.

        The match giving you your immediate trouble is against the default variable ($_), but nothing assigns a value to it, hence it is uninitialized (the immediate error). But it is not at all clear what value should be assigned to it.


        Perl is environmentally friendly - it saves trees
        if (my($ip,$date,$method,$url,$query,$protocol,$retcode,$byte)=($s_=~ +m/$LOG_PATTERN/)) # + ^
Re: search pattern not terminated
by ww (Archbishop) on Jan 22, 2008 at 02:32 UTC

    This does not capture all you wanted but perhaps you can build on this:

    #!/usr/bin/perl use strict; use warnings; my $log=q<10.25.95.100 ab - [05/Aug/2003:12:00:30 -0700] "GET /creativ +e/2|2127274-1>; # note 1 (re above) # print "\$log is $log \n"; # note 2 if ( $log =~ / (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) # capture IP digits \s[a-z]{2,2}\s-\s\[ # match but don't capture spa +ce, dash, space (\d+\/[A-Z][a-z]{2,2}\/\d{4,4}) # capture the date : # don't capture the perlimina +ry colon (\d+:\d+:\d+\s-\d{4,4}) # capture time with colons &a +mp; GMT offset (.*) # dot-slash deprecated, but c +apture to end /x ) { # extended notation, end cond +it, print print "\$1=$1, \$2=$2, \$3=$3, \$4 = $4 \n"; # note 3 } else { print "no matches\n"; } # note 4
    ... balance of code (Update: ...as corrected in other nodes and restoring the full original string to $log/$s)

    1 "$s" may be less than clear, a few hundred lines later; use a meaningful name for the $var
    2 I read this as OP's simple test to make sure the assignment above worked.
    3 It would be better to make this
     print "IP = $1, DATE = $2, TIME= $3"and so on, if you're merely testing your regex
    4 added the conditional: ALWAYS test captures before trying to use them

Re: search pattern not terminated
by ww (Archbishop) on Jan 21, 2008 at 23:55 UTC

    It helps if you format your post properly (see Writeup Formatting Tips ) (Update OP updated without notice) and if you quote the entire output...

    Unmatched ) in regex; marked by <-- HERE in m/(.*) \- \(.*) <-- HERE \ "(.*) (.*)\?(.*) HTTP/(.*)" (0-9*) (0-9*) "(.*)" "(.*)"/ at (yourcode).pl line 7. Now, I admit, counting paren_matches and so forth, it's not immediately obvious to me, either, why that occurs, but wiser heads would have had more to work on had you investigated the norms here ( How do I post a question effectively? ) before posting.
Re: search pattern not terminated
by poolpi (Hermit) on Jan 22, 2008 at 08:11 UTC