Perl Regular Expression Matching

I want to combine two different lines, and the output should consist of $ 1 and $ 2. According to me in this example, if $ a is "xy abc", then $ 1 should be "xy abc", and $ 2 should be "abc", but part " abc "is at $ 3. Could you help me write a regular expression in that $ 1 must contain the whole string, and $ 2 is the second part. I am using perl 5.8.5.

my @data=('abc xy','xy abc');
foreach my $a ( @data) {
    print "\nPattern= $a\n";
    if($a=~/(abc (xy)|xy (abc))/) {
        print "\nMatch: \$1>$1< \$2>$2< \$3>$3<\n";
    }
}

Output:

perl test_reg.pl

Pattern= abc xy

Match: $1>abc xy< $2>xy< $3><

Pattern= xy abc

Match: $1>xy abc< $2>< $3>abc<
+5
source share
3 answers

Since only one of the captures can be defined $2and $3, you can write

foreach my $item ( @data) {

  print "\nPattern= $item\n";

  if ($item=~/(abc (xy)|xy (abc))/) {
    printf "Match: whole>%s< part>%s<\n", $1, $2 || $3;
  }
}

which gives way

Pattern= abc xy
Match: whole>abc xy< part>xy<

Pattern= xy abc
Match: whole>xy abc< part>abc<
+1
source

Can be done with:

(?|(abc (xy))|(xy (abc)))

? $& .

my @data = ('abc xy', 'xy abc');
for(@data) {
    print "String: '$_'\n";

    if(/(?|abc (xy)|xy (abc))/) {
        print "Match: \$&='$&', \$1='$1'\n";
    }
}
+4

If you can live with the possibility of more capture variables than $1and $2, use substrings from the alternative branch that matches.

for ('abc xy', 'xy abc') {
  print "[$_]:\n";

  if (/(abc (xy))|(xy (abc))/) {
    print "  - match: ", defined $1 ? "1: [$1], 2: [$2]\n"
                                    : "1: [$3], 2: [$4]\n";
  }
  else {
    print "  - no match\n";
  }
}

Conclusion:

[abc xy]:
  - match: 1: [abc xy], 2: [xy]
[xy abc]:
  - match: 1: [xy abc], 2: [abc]
0
source

All Articles