2

For example,

@seed = ('seed_1', 'seed_2', 'seed_3', 'seed_4);

However, in the future there could be more than seed_4. How can I make this as general as possible? Meaning I don't have to manually write the future seed_. It can be 'seed_50' or random values.

example:

$file ='text.txt';
for my $seed (@seed)
 {
   if (open my $data, "<", $file)
    {
      my $line =<$data>;
      print "ERROR: $line\n";
    }
   close $data;
}

the seed_ are actually folders in directories. So, I need to go through every seed to open the text file but I may not know the values in every seed folder. The dir are directories I need to open. I just need to read out the first line of the text.

so for example:

for my $dir (@dir){
    for my $seed (@seed)
     {
       if (open my $data, "<", $file)
        {
          my $line =<$data>;
          print "ERROR: $line\n";
        }
       close $data;
    }
}
8
  • 1
    perhaps even seed_\d+. Commented Oct 20, 2020 at 2:13
  • 1
    @ikegami I have @array = ('seed_1', 'seed_2', 'seed_3', 'seed_4');. But in the future, there may be more than this. Is there a way to automatically match the pattern without writing out manually the seed_ ? Commented Oct 20, 2020 at 3:29
  • 1
    Thank you for editing and adding an example. Can you add more to show how is regex with @seed elements involved? (Do you mean to test whether any of $seed matches, for each $line? Or something else?) Commented Oct 20, 2020 at 4:51
  • 1
    (I mean even just adding a comment to the code would clarify it (like # check whether $seed matches $line or some such) Commented Oct 20, 2020 at 5:13
  • 1
    Your example doesn't use $seed?!? Did you use $file where you meant to use $seed? If so, you want glob("\Q$dir\E/seed*") Commented Oct 20, 2020 at 6:13

1 Answer 1

5

Escape possible non-"word" ASCII characters in the array elements using quotemeta, and build a pattern with them using alternation

my $pattern = join '|', map { quotemeta } @ary;

Then use this $pattern in a regex pattern

if ( $string =~ /$pattern/ ) { say $& }

to find the first of elements that matches in the $string (if any), or

while ( $string =~ /$pattern/g ) { say $& }

to iterate over all matches, etc.

Depending on the details it may be necessary to sort the array first.

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

6 Comments

Hi, thank you for suggesting this. I tried it and it works. However, if my array increases such as there are seed_1 till seed_10 or random numbers behind seed_, do i have to manually type it out in the @seed?
@AlyssaLow No, you never need to type specific elements; that is the point. The code never names what is in the array -- the whole array is used, whether it has two elements or a thousand. The map applies quotemeta (which escapes special characters if there are any) to every element of whatever list you give it, then all those are join'-ed with |. The only specific item to provide is the array name (@seed in your case instead of @ary here)
@AlyssaLow The code uses the array (@seed in your case) with all its elements. The array itself has to be formed somehow elsewhere in the code; either you type in those elements, read them from a file, compute them at runtime ... it depends on how your program operates.
Ohh okay, thank you for the explanation. I'll give it a try.
Any benefits of making a compiled regex? my ($pattern) = map { qr/$_/ } ..
|

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.