ruggedbuteducated
ruggedbuteducated

Reputation: 1348

pattern matching in regular expression (Perl)

Make a pattern that will match three consecutive copies of whatever is currently contained in $what. That is, if $what is fred, your pattern should match fredfredfred. If $what is fred|barney, your pattern should match fredfredbarney, barneyfredfred, barneybarneybarney, or many other variations. (Hint: You should set $what at the top of the pattern test program with a statement like my $what = 'fred|barney';)

But my solution to this is just too easy so I'm assuming its wrong. My solution is:

#! usr/bin/perl
use warnings;
use strict;


while (<>){
chomp;

if (/fred|barney/ig) {
    print "pattern found! \n";
}
}

It display what I want. And I didn't even have to save the pattern in a variable. Can someone help me through this? Or enlighten me if I'm doing/understanding the problem wrong?

Upvotes: 3

Views: 263

Answers (2)

chrsblck
chrsblck

Reputation: 4088

This example should clear up what was wrong with your solution:

my @tests = qw(xxxfooxx oofoobar bar bax rrrbarrrrr);
my $str = 'foo|bar';

for my $test (@tests) {
    my $match = $test =~ /$str/ig ? 'match' : 'not match';
    print "$test did $match\n";
}

OUTPUT

xxxfooxx did match
oofoobar did match
bar did match
bax did not match
rrrbarrrrr did match 

SOLUTION

#!/usr/bin/perl

use warnings;
use strict;

# notice the example has the `|`. Meaning 
# match "fred" or "barney" 3 times. 
my $str = 'fred|barney';
my @tests = qw(fred fredfredfred barney barneybarneybarny barneyfredbarney);

for my $test (@tests) {
    if( $test =~ /^($str){3}$/ ) {
        print "$test matched!\n";
    } else {
        print "$test did not match!\n";
    }
}

OUTPUT

$ ./test.pl
fred did not match!
fredfredfred matched!
barney did not match!
barneybarneybarny did not match!
barneyfredbarney matched!

Upvotes: 2

Steve P.
Steve P.

Reputation: 14699

use strict;
use warnings;

my $s="barney/fred";
my @ra=split("/", $s);
my $test="barneybarneyfred"; #etc, this will work on all permutations

if ($test =~ /^(?:$ra[0]|$ra[1]){3}$/)
{
    print "Valid\n";
}
else
{
    print "Invalid\n";
}

Split delimited your string based off of "/". (?:$ra[0]|$ra[1]) says group, but do not extract, "barney" or "fred", {3} says exactly three copies. Add an i after the closing "/" if the case doesn't matter. The ^ says "begins with," and the $ says "ends with."

EDIT: If you need the format to be barney\fred, use this:

my $s="barney\\fred";
my @ra=split(/\\/, $s);

If you know that the matching will always be on fred and barney, then you can just replace $ra[0], $ra[1] with fred and barney.

Upvotes: 1

Related Questions