Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to user Perl to find all instances of strings that match a regexp?

Tags:

regex

perl

How to user Perl to find and print all strings that match a regexp?

The following only finds the first match.

$text="?Adsfsadfgaasdf.
?Bafadfdsaadsfadsf.
xcxvfdgfdg";

if($text =~ m/\\?([^\.]+\.)/) {
    print "$1\n";
}

EDIT1: /g doesn't work

#!/usr/bin/env perl

$text="?Adsfsadfgaasdf.
?Bafadfdsaadsfadsf.
xcxvfdgfdg";

if($text =~ m/\\?([^\.]+\.)/g) {
    print "$1\n";
}

$ ./test.pl 
?Adsfsadfgaasdf.
like image 886
qazwsx Avatar asked Feb 02 '23 09:02

qazwsx


2 Answers

The problem is that the /g modifier does not use capture groups for multiple matches. You need to either iterate over the matches in scalar context, or catch the returned list in list context. For example:

use v5.10; # required for say()
$text="?Adsfsadfgaasdf.
?Bafadfdsaadsfadsf.
xcxvfdgfdg";

while ($text =~ /\?([^.]+\.)/g) {  # scalar context
    say $1;
}
for ($text =~ /\?[^.]+\./g) {     # list context
    say;               # match is held in $_
}

Note in the second case, I skipped the parens, because in list context the whole match is returned if there are no parens. You may add parens to select part of the string.

Your version, using if, uses scalar context, which saves the position of the most recent match, but does not continue. A way to see what happens is:

if($text =~ m/\?([^\.]+\.)/g) {
    print "$1\n";
}
say "Rest of string: ", substr $text, pos;

pos gives the position of the most recent match.

like image 121
TLP Avatar answered Feb 05 '23 17:02

TLP


In previous answer @TLP correctly wrote that matching should be in list context.

use Data::Dumper;

$text="?Adsfsadfgaasdf.
?Bafadfdsaa.
dsfadsf.
xcxvfdgfdg";

@arr = ($text =~ /\?([^\.]+\.)/g);

print Dumper(@arr);

Expected result:

$VAR1 = 'Adsfsadfgaasdf.';
$VAR2 = 'Bafadfdsaa.';
like image 28
Taras Avatar answered Feb 05 '23 18:02

Taras