KVon KVon - 2 months ago 15
Perl Question

How to match multiple groups on a specific line in Perl, but not other lines?

I understand the /g flag and I'm able to match a pattern multiple times, but I'm having a difficult time researching this particular question.

Say my string has multiple lines and I want to match a grouped pattern on a line that contains a specific word, but not on a different line that doesn't.

For an example string

with multiple lines

Unimportant line.
Important line with !special1! word and !special2! word.
Extra line with !special3! word and !special4! word.

I want to print the two specials on the important line but not the extra line, so the result would be:

special1, special2

I can match every special using /g

my @both = $test =~ /!(.+?)!/g;
print join(', ', @both);

But the output is:

special1, special2, special3, special4

If I try to include the word 'Important'

my @both = $test =~ /Important.+?!(.+?)!/g;
print join(', ', @both);

I just get


I understand it only matches once because 'Important' only occurs once, but I can't figure out how to get the output

special1, special2


There are a number of ways to do this. I think the most solid approach is to break your string into lines and iterate over that array. Then you can choose how to select what you need. For example

my @lines = split '\n', $test;

foreach my $line (@lines)
    next if $line !~ /^Important/;

    my @all_on_line = $line =~ /!(.+?)!/g;

    print join(', ', @all_on_line), "\n";

I assumed that Important is at the beginning of the wanted line. Adjust as needed.

Packing this into a single regex is quite a bit more involved.