Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3849640
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 19, 20262026-05-19T16:53:12+00:00 2026-05-19T16:53:12+00:00

I have to find all the positions of matching strings within a larger string

  • 0

I have to find all the positions of matching strings within a larger string using a while loop, and as a second method using a foreach loop. I have figured out the while loop method, but I am stuck on a foreach method. Here is the ‘while’ method:

….

my $sequence = 
   'AACAAATTGAAACAATAAACAGAAACAAAAATGGATGCGATCAAGAAAAAGATGC'.
   'AGGCGATGAAAATCGAGAAGGATAACGCTCTCGATCGAGCCGATGCCGCGGAAGA'.
   'AAAAGTACGTCAAATGACGGAAAAGTTGGAACGAATCGAGGAAGAACTACGTGAT'.
   'ACCCAGAAAAAGATGATGCNAACTGAAAATGATTTAGATAAAGCACAGGAAGATT'.
   'TATCTGTTGCAAATACCAACTTGGAAGATAAGGAAAAGAAAGTTCAAGAGGCGGA'.
   'GGCTGAGGTAGCANCCCTGAATCGTCGTATGACACTTCTGGAAGAGGAATTGGAA'.
   'CGAGCTGAGGAACGTTTGAAGATTGCAACGGATAAATTGGAAGAAGCAACACATA'.
   'CAGCTGATGAATCTGAACGTGTTCGCNAGGTTATGGAAA';

my $string = <STDIN>;
chomp $string;

while ($sequence =~ /$string/gi )
{
 printf "Sequence found at position: %d\n", pos($sequence)- length($string);
}

Here is my foreach method:

foreach  ($sequence =~ /$string/gi ) 

 printf "Sequence found at position: %d\n", pos($sequence) - length($string); 
}

Could someone please give me a clue on why it doesn’t work the same way?
Thanks!

My Output if I input “aaca”:

Part 1 using a while loop
Sequence found at position: 0
Sequence found at position: 10
Sequence found at position: 17
Sequence found at position: 23
Sequence found at position: 377

Part 2 using a foreach loop
Sequence found at position: -4
Sequence found at position: -4
Sequence found at position: -4
Sequence found at position: -4
Sequence found at position: -4
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-19T16:53:13+00:00Added an answer on May 19, 2026 at 4:53 pm

    Your problem here is context. In the while loop, the condition is in scalar context. In scalar context, the match operator in g mode will sequentially match along the string. Thus checking pos within the loop does what you want.

    In the foreach loop, the condition is in list context. In list context, the match operator in g mode will return a list of all matches (and it will calculate all of the matches before the loop body is ever entered). foreach is then loading the matches one by one into $_ for you, but you are never using the variable. pos in the body of the loop is not useful as it contains the result after the matches have ended.

    The takeaway here is that if you want pos to work, and you are using the g modifier, you should use the while loop which imposes scalar context and makes the regex iterate across the matches in the string.

    Sinan inspired me to write a few foreach examples:

    • This one is fairly succinct using split in separator retention mode:

      my $pos = 0;
      foreach (split /($string)/i => $sequence) {
          print "Sequence found at position: $pos\n" if lc eq lc $string;
          $pos += length;
      }
      
    • A regex equivalent of the split solution:

      my $pos = 0;
      foreach ($sequence =~ /(\Q$string\E|(?:(?!\Q$string\E).)+)/gi) {
          print "Sequence found at position: $pos\n" if lc eq lc $string;
          $pos += length;
      }
      
    • But this is clearly the best solution for your problem:

      {package Dumb::Homework;
          sub TIEARRAY {
              bless {
                  haystack => $_[1],
                  needle   => $_[2],
                  size     => 2**31-1,
                  pos      => [],
              }
          }
          sub FETCH {
              my ($self, $index) = @_;
              my ($pos, $needle) = @$self{qw(pos needle)};
      
              return $$pos[$index] if $index < @$pos;
      
              while ($index + 1 >= @$pos) {
                  unless ($$self{haystack} =~ /\Q$needle/gi) {
                      $$self{size} = @$pos;
                      last
                  }
                  push @$pos, pos ($$self{haystack}) - length $needle;
              }
              $$pos[$index]
          }
          sub FETCHSIZE {$_[0]{size}}
      }
      
      tie my @pos, 'Dumb::Homework' => $sequence, $string;
      
      print "Sequence found at position: $_\n" foreach @pos; # look how clean it is
      

      The reason its the best is because the other two solutions have to process the entire global match first, before you ever see a result. For large inputs (like DNA) that could be a problem. The Dumb::Homework package implements an array that will lazily find the next position each time the foreach iterator asks for it. It will even store the positions so you can get to them again without reprocessing. (In truth it looks one match past the requested match, this allows it to end properly in the foreach, but still much better than processing the whole list)

    • Actually, the best solution is still to not use foreach as it is not the correct tool for the job.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a program where I need to find all instances of a class
I have this line: @users = database['users'].find(:all).limit(10) it returns this object: <Mongo::Cursor:0x8759a858 namespace='app-development.users' @selector=:all
How to find all files in directory? I have HTML page in some directory.
I need to find all patrons that have at least 1 circulation record. Here's
How can I find all column values in a column which have trailing spaces?
I have borrowed code from this link PHP regex templating - find all occurrences
Considering that I have a Schema named SBST I want to find all empty
I have to find all possible pairs in a list, the following way: given
I'd like to find all unique combinations of element positions of an array in
How do you show all the matches?For example I have one String Hello world

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.