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

Hi monks, ive some prroblem with my pattern mathcing problem, I am trying to print the string that containts specific characters with the position of that string in a file, but the only thng that i can get is, the location of that string in a file.

Here is my code :
use CGI; my $cgi = new CGI; print $cgi->header('text/html'); my $dir = 'C:\\inetpub\\wwwroot\\vortragsreihe_DEV\\'; my $book = $dir.'dir.txt'; opendir(DIR, $dir) or die $!; open FILE, '>'.$book; while (my $file = readdir(DIR)) { if(-f $dir.$file){ # Use a regular expression to ignore files beginning with +a period next if ($file =~ m/^\./); print FILE "C:\\inetpub\\wwwroot\\vortragsreihe_DEV\\$file +\n"; } } close FILE; closedir(DIR); open (DATEI, '<' . 'C:\\inetpub\\wwwroot\\vortragsreihe_DEV\\dir.txt') + || die "Datei nicht gefunden $!"; my @daten = <DATEI>; close (DATEI); chomp(@daten); my $number = 0; my %params = $cgi->Vars; my $string = quotemeta("$test"); foreach(@daten){ print "finding -$string- in $daten[$number]\n"."</br>" +; open(my $file, "<", "$daten[$number]") or die "Can' +t open the file: $!"; my $num = 1; while (<$file>) { if (/$string/) { my $content =~ m/(\/$string\/[a-z]*)/g; print $content; print "found string -$string- in line $num + \n"; print "<br>"; } $num++; } $number++; }
and the result is (if we search 'a') : found string -a- in line 2, however i expect the it prints the whole string so when i search the word that starts with 'a', it will return the word like 'air'. any help will be appriciated

Replies are listed 'Best First'.
Re: Pattern Matching problem
by choroba (Cardinal) on Jun 04, 2013 at 12:06 UTC
    You are printing $string which contains only "a". If you want to print the match, store it for printing later:
    if (my ($match) = /(\Q$string\E\S*)/) { print "Matched '$string' in '$match'.\n"; }

    Note that

    my $content =~ m/.../g;

    is not doing what you think. By adding my, you make $content undefined, so matching it against anything non-empty returns false. You should use warnings which would tell you:

    Use of uninitialized value $content in pattern match (m//)
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Pattern Matching problem
by hdb (Monsignor) on Jun 04, 2013 at 12:05 UTC

    Please use code tags!

    Your problem lies in the line

    my $content =~ m/(\/$string\/a-z*)/g;

    This tries to match your pattern against the string in $content which is not defined at this point in time. You could try something like:

    my @content = $_ =~ m/(\/$string\/a-z*)/g;

    which captures all matches into the array @content.

    What is also funny about your code is the loop foreach(@daten){. You do not seem to be using the elements of @daten anywhere. Should this not be something like foreach my $daten (@daten){?

      can i just post my whole code? so you can analyze my problem? ive tried the whole solution but it still does not work

        If it is not tons of lines...
        It would also be good if it runs standalone without requiring any extra inputs, files etc.

Re: Big problem in pattern matching
by kennethk (Abbot) on Jun 04, 2013 at 14:38 UTC

    There's a lot going on in your code; both as a debugging exercise and a convenience to those who would like to help you, you should try to simplify your posts down to the most compact code that replicates your issue. It has been my experience that bugs often identify themselves when I try to isolate them. See How do I post a question effectively?.

    Your variable $string contains the escaped contents of the variable $test, which is never initialized in your code. I'm thinking this is an error in your post, not if your original code. Please make sure that posted code replicates what you are actually running, so we can debug the right thing. In this case, both strict and warnings would have flagged the issue. See Use strict warnings and diagnostics or die.

    If I'm reading your spec right, your line featuring my $content =~ ... is supposed to grab the entire 'word' following your match. However, because you've used the binding operator (=~), you are actually running your regular expression against an uninitialized value (again, an issue caught by warnings). What you probably meant to do was

    my ($content) = m/($string[a-z]*)/;

    This runs the previous expression extended to include all trailing lower-case alphabetic characters, extracts the match, and uses list assignment to store the match (List value constructors). Easier would be to run the code as

    if (/$string/) { m/($string[a-z]*)/; print "$1\n"; print "found string -$string- in line $num +\n"; print "<br>"; }
    since capturing stores the value in $1 (Variables related to regular expressions). Note that I've removed the g modifier and escaped slashes because I don't think that's what you meant.

    Let me know if I've missed the spec here.


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      I changed my code, and it works pretty find.

      #!/usr/bin/perl use CGI; my $cgi = new CGI; print $cgi->header('text/html'); if (defined $cgi->param('ok')) { my $dir = 'C:\\inetpub\\wwwroot\\vortragsreihe_DEV\\'; my $book = $dir.'dir.txt'; opendir(DIR, $dir) or die $!; open FILE, '>'.$book; while (my $file = readdir(DIR)) { if(-f $dir.$file){ # Use a regular expression to ignore files beginning with +a period next if ($file =~ m/^\./); print FILE "C:\\inetpub\\wwwroot\\vortragsreihe_DEV\\$file +\n"; } } close FILE; closedir(DIR); open (DATEI, '<' . 'C:\\inetpub\\wwwroot\\vortragsreihe_DEV\\dir.txt') + || die "Datei nicht gefunden $!"; my @daten = <DATEI>; close (DATEI); chomp(@daten); my $number = 0; my %params = $cgi->Vars; my $string = $cgi->param('string'); foreach(@daten){ print "finding -$string- in $daten[$number]\n"."</br>" +; open(my $file, "<", "$daten[$number]") or die "Can' +t open the file: $!"; my $num = 1; while (<$file>) { if (/$string/) { if (my ($match) = /(\Q$string\E\S*)/) { print "Matched '$string' in '$match' in li +ne $num"."<br />"; } # my $content =~ m/(\/$string\/[a-z]*)/g; # print $content; # print "found string -$string- in line $n +um \n"; # print "<br>"; } $num++; } $number++; } } else { print <<ENDHTML; <HTML> <BODY> <FORM name = "ariau" METHOD=GET ACTION="search.pl"> name: <INPUT TYPE=TEXT NAME="string" VALUE = ""><BR> <INPUT TYPE=SUBMIT NAME="ok" Value = "ok"> </FORM> </BODY> </HTML> ENDHTML }

      but the problem is, I can not search the string that started with particular symbol, such as, i cant search something like '$test', any help will be appreciated

        Remove
        if (/$string/) {

        or change it to

        if (/\Q$string\E/) {
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ