3

Sorry if it is a duplicate topic, but I've searched inside the forum and I've only found similar but not identical questions.

My problem is:

I've got an array of strings like this one:

@array = ("My name is "Annie" \n", "My mother's name was "Annie", too. \n", "I am "27" years old \n", "I live in "Minnesota" \n");

And another array of strings like this one:

@subs = ("Annie", "22", "Minnesota");

I would like to:

1) find any occurrence of the words from the second array in the first array (for instance: Annie would match with the first and the second element, Minnesota only with the last one).

2) substitute all the words which matched with any element of the second array with the same word followed by "-DATA" (for instance: "My name is "Annie-DATA"\n").

I guess that this could be easily done with one or two for loops, but I'm wondering if there's any quicker way, maybe with some smart use of PERL's regexs.

Thank you!

2
  • 1
    The real problem should not be adding -DATA or is it? There could be a better way to look at the problem. Commented Apr 4, 2013 at 12:57
  • What do you mean? Maybe I should specify that the real i/o of my program is much more complicated than this example I posted. However, I also have the feeling that I may be facing the problem the wrong way because this part of my algorithm (not shown here) feels a bit muddled, so you could be right. Commented Apr 4, 2013 at 13:07

3 Answers 3

2

You could replace like this:

s/(Annie|22|Minnesota)/\1-DATA/g
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! Only a question: but what if I don't know in advance the 3 key words I've to match (in this case, Annie, 22, Minnesota), but they come from an array which can change both in length and content?
$sub = join '|', @sub; s/($sub)/\1-DATA/g;
2

One solution:

use strict;
use warnings;
my @array = ("My name is \"Annie\" \n",
   "My mother's name was \"Annie\", too. \n",
   "I am \"27\" years old \n",
   "I live in \"Minnesota\" \n");
my @subs = ("Annie", "22", "Minnesota");

my @new_array = map { my $line = $_; 
                      $line =~ s/$_/$_-DATA/g foreach @subs; 
                      $line } @array;

Comments

1

Another solution which also escapes meta chars:

# escape possible meta characters and join
my $sub = join '|', map { quotemeta } @subs;

# replace in the array
s/($sub)/$1-DATA/g for @array;

If you don't want to change the values directly in @array use map instead of for. Eg: my @new = map s/($sub)/$1-DATA/g, @array;

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.