1

I'm trying to grep a special pattern in an array of strings.

My array of strings is like this :

@list=("First phrase with \"blabla - Word\" and other things "
      ,"A phrase without... "
      ,"Second phrase with \"truc - Word\" and etc... "
      ,"Another phrase without... "
      ,"Another phrase with \"thing - Word\" and etc... ");

and I tried to grep the pattern "..... - Word" with this function :

@keyw = grep { /\".* Word\"/} (@list);

and I have the following result :

print  (Dumper  (  @keyw));
$VAR1 = 'First phrase with "blabla - Word" and other things ';
$VAR2 = 'Second phrase with "truc - Word" and etc... ';
$VAR3 = 'Another phrase with "thing - Word" and etc... ';

My grep function is ok to grep the phrase but I would like to grep just the pattern and get the following result :

$VAR1 = '"blabla - Word"';
$VAR2 = '"truc - Word"';
$VAR3 = '"thing - Word"';

Do you know how to reach this result ?

2 Answers 2

4

Use map instead of grep:

my @keyw = map { /\"[^"]*? Word\"/ ? $& : () } @list;

It just returns $& (whole match) if the pattern matches and () (empty list) if it does not.
Little caveat: don't use $& with with Perl < 5.18.0.

Here's Casimir et Hippolyte's simpler solution:

my @keyw = map { /(\"[^"]*? Word\")/ } @list;

It works since m// returns a list of captured groups.

Sign up to request clarification or add additional context in comments.

4 Comments

instead of using the ternary operator and $&, you can use a capture group. See the performance issue about using $&: perldoc.perl.org/perlvar.html . Note that the original pattern can be more waterproof if the dot is replaced (at least) with [^"]
@CasimiretHippolyte hmm... not sure I understand what you're suggesting. Returning anything short of () yields undef values in the resulting array. The performance issue of $& was solved long ago. You're right about [^"].
I was thinking about: my @keyw = map {/(\".* Word\")/} @list;
@CasimiretHippolyte d'oh, I see, thanks :) My Perl is getting rusty.
2

Why can't we just use a normal loop?

use strict;
use warnings;

use Data::Dump;

my @phrases = (
    "First phrase with \"blabla - Word\" and other things ",
    "A phrase without... ",
    "Second phrase with \"truc - Word\" and etc... ",
    "Another phrase without... ",
    "Another phrase with \"thing - Word\" and etc... ",
);

my @matches;

for (@phrases) {
    next unless /("[^"]+Word")/;
    push(@matches, $1);
}

# prints ["\"blabla - Word\"", "\"truc - Word\"", "\"thing - Word\""]
dd(\@matches);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.