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

I'm trying to match against an array trying to find this pattern
filename="Hare.java"
and this is the code I have:
while ($_myfile[$i] !~ /filename="(.*)\.(.*)"){$args1=$1;$args2=$2;pri +nt $args2;$i++;}

can anyone tell me why this might not work, I get a message saying that use of initialized value in print at filename ....?

Edit ar0n -- Fixed formatting/moved to SoPW

Replies are listed 'Best First'.
Re: pattern matching
by derby (Abbot) on Mar 29, 2002 at 02:33 UTC
    perldoc perlop and look at the section called "Binding Operators" and the difference between !~ and =~. I think you want the latter and not the former.

    -derby

Re: pattern matching
by RMGir (Prior) on Mar 29, 2002 at 02:37 UTC
    I guess your code is really
    while ($_myfile[$i] !~ /filename="(.*)\.(.*)"/) { $args1=$1; $args2=$2; print $args2; $i++; }
    with the closing / on the regex?

    The problem is that !~ means DON'T match. What you want is probably

    while ($_myfile[$i] =~ /filename="(.*)\.(.*)"/) { $args1=$1; $args2=$2; print $args2; $i++; }
    Hope this helps!
    --
    Mike
It's Not Clear What You're Doing - Re: pattern matching
by metadoktor (Hermit) on Mar 29, 2002 at 02:43 UTC
    I think that your code has some really serious problems if you posted it without errors. I'm not sure what you're attempting with $_myfile[$i]? Perhaps you meant $_[$i] or $myfile[$i]? Also the regex you attempted does not have a trailing / (forward slash). Also the 'filename' variable you posted should be '$filename'.

    Something like the following should work assuming that @myfile has been defined to be an array and contains the required filenames.

    for (@myfile) { if (/$filename/) { print "Found pattern.\n"; } }
    Now another problem is that you seem to want to extract some substrings from the matched string by your use of parens in the regex yet it is unclear what you're trying to do here since you already know that the pattern is 'Hare.java' or is it?

    metadoktor

    "The doktor is in."

Re: pattern matching
by erikharrison (Deacon) on Mar 29, 2002 at 02:45 UTC

    Most of the time these kind of error messages (I'm assuming you meant uninitialized) only occur under -w and use strict (which are good things!)

    Not quite sure exactly what you're trying to do, but here's code that I think'll do it. See if this will fit what you need, and ask if you don't understand.

    @foobar = qw('This=that', 'Mine=Yours', 'We=Them'); print map { /(?:.*)_(.*)/; $1 } @foobar;
    Cheers,
    Erik
Re: pattern matching
by dragonchild (Archbishop) on Mar 29, 2002 at 14:43 UTC
    I'm shocked that no-one mentioned the really obvious solution - don't use a regex!
    my $i = 0; while (my ($args1, $args2) = split('.', $_myfile[$i++])) { print "$args2\n"; }
    If you're parsing, a regex should be your last resort. You should have at least considered the following options first:
    1. Judicious use of split. (In the case above, we would've needed another split.) Use this if you have delimiters (like a period?)
    2. Judicious use of unpack. Use this if your data is column-formatted. (Most work with mainframes or network protocols will use unpack, for example.)
    3. Now, and only now, should regexes be used. Regexes should be used if the above do not apply. They are harder to maintain and, if you don't know what you're doing, can be the cause of subtle bugs.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      Er, hang on, the first argument to split is a regular expression - however it is quoted. Your snippet will split on any any character - and thus nothing will be assigned to $args1 and $args2. This can be demonstrated by the following :

      #!/usr/bin/perl -w use strict; my $string = 'this is a test'; my @foo = split('(.)', $string); print join('*',@foo);
      If you read the perlfunc entry for split you will see that using the '()' in the regular expression includes the delimiting character in the output substrings.

      /J\