[Solved] Perl Programming


You’re talking about regular expressions and how to use them in Perl. Your question seems to be whether the answers you picked to homework are correct.

The code you’ve added should do what you want, but it has syntax errors.

if ( ^x*$ ) {
    print "This is";
}

Your pattern is correct, but you don’t know how to use a regular expression in Perl. You’re missing the actual operator to tell Perl that you want a regular expression.

The short form is this, where I’ve highlighted the important part with #

if ( /^x*$/ ) {
     #    #

The slashes // tell Perl that it should match a pattern. The long form of it is:

if ( $_ =~ m/^x*$/ ) {
     ## ## ##    #

$_ is the variable that you are matching against a pattern. The =~ is the matching operator. The m// constructs a pattern to match with. If you use // you can leave out the m, but it’s clearer to put it in.

The $_ is called topic. It’s like a default variable that stuff goes into in Perl if you don’t specify another variable.

while ( <$fh> ) {
    print $_ if $_ =~ m/foo/; # print all lines that contain foo
}

This code can be written as $_, because a lot of commands in Perl assume that you mean $_ when you don’t explicitly name a variable.

while ( <$fh> ) {    # puts each line in $_
    print if m/foo/; # prints $_ if $_ contains foo
}

You code looks like you wanted to do that, but in fact you have a $row in your loop. That’s good, because it is more explicit. That means it’s easier to read. So what you need to do for your match is:

while ( my $row = <$fh> ) {
    if ( $row =~ m/^x*$/ ) {
        print "This is";
    }
}

Now you will iterate each line of the file behind the $fh filehandle, and check if it matches the pattern ^x*$. If it does, you print _”This is”. That doesn’t sound very useful.

Consider this example, where I am using the __DATA__ section instead of a file.

use strict;
use warnings;

while ( my $row = <DATA> ) {
    if ( $row =~ m/^x*$/ ) {
        print "This is";
    }
}

__DATA__
foo
xxx

x
xxxxx
bar

This will print:

This isThis isThis isThis is

It really does not seem to be very useful. It would make more sense to include the line that matched.

if ( $row =~ m/^x*$/ ) {
    print "match: $row";
}

Now we get this:

match: xxx
match: 
match: x
match: xxxxx

That’s almost what we expected. It matches a single x, and a bunch of xs. It did not match foo or bar. But it does match an empty line.

That’s because you picked the wrong pattern.

The * multiplier means match as many as possible, as least none.
The + multiplier means match as many as possible, at least one.

So your pattern should be the one with +, or it will match if there is nothing, because start of the line, no x, end of the line matches an empty line.

While you’re at it, you could also rename your variable. Unless you’re dealing with CSV, which has rows of data, you have lines, not rows. So $line would be a better name for your variable. Giving variables good, descriptive names is very important because it makes it easier to understand your program.

use strict;
use warnings;

my $filename="data.txt";

open( my $fh, '<:encoding(UTF-8)', $filename ) 
    or die "Could not open file '$filename' $!";

while ( my $line = <$fh> ) {
    if ( $line =~ m/^x+$/ ) {
        print "match: $line";
    }
}

solved Perl Programming