Finding and printing a specific Pattern in a given string
<p>I am writing a code find a specific pattern in a given string using python or perl. I had some success in finding the pattern using C but python or perl usage is mandatory for this assignment and I am very new in both of these lanuages.</p>

<p>My string looks like this (Amino acid sequence) :-</p>

<pre><code> MKTSGNQDEILVIRKGWLTINNIGIMKGGSKEYWFVLTAENLSWYKDDEEKEKKYMLSVDNLKLRDVEKGFMSSKHIFAL
</code></pre>

<p>The pattern I want to find is </p>

<pre><code> KXXXXXX(K\R)XR 
</code></pre>

<p>Please note that Letters between K and K\R are not fixed. However, there is only letter between K\R and R. So, in the given string my pattern is like this and exist between letter no. 54 to 65 (if I counted correctly) based on "smallest pattern" search :-</p>

<pre><code>  KYMLSVDNLKLR
</code></pre>

<p>Previously, I was using C if-else condition to break this given string and printed out word count (not fully successful).</p>

<pre><code>   printf(%c, word[i]);
     if ((word [i] == 'K' || word [i] == 'R' )) &amp;&amp; word [i+2] == 'R') {
        printf("\n");
        printf("%d\n",i);
    }
</code></pre>

<p>I agree It dint capture everything. If anyone can help me help me solving this problem, that would be great.</p>

<p>Only did it this way because I hate back tracking in my regular expressions.  But I do find its usually faster if I perform the most restrictive part of the match first.  Which in this case is made simpler by reversing the input and the search pattern.  This should stop at the first (shortest) possible match; rather than finding the longest match, then hunting down the shortest. </p>

<pre><code>#!/usr/bin/perl
use strict;
use warnings;

my $pattern = "MKTSGNQDEILVIRKGWLTINNIGIMKGGSKEYWFVLTAENLSWYKDDEEKEKKYMLSVDNLKLRDVEKGFMSSKHIFAL";
my $reverse = reverse $pattern;
my $length  = length $reverse;
if( $reverse =~ /(R.[KR][^K]+K)/ ) {
    my $match   = $1;
    $match      = reverse $match;
    my $start_p = $length-$+[0];
    my $end_p   = $length-$-[0]-1;
    my $where   = $start_p + length $match;
    print "FOUND ...\n";
    print "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\n";
    print $pattern."\n";
    printf "%${where}s\n", $match;
    print "Found pattern '$match' starting at position '$start_p' and ending at position '$end_p'\n";
    # test it
    if( $pattern =~ /$match/ ) {
        if( $start_p == $-[0] &amp;&amp; $end_p == $+[0]-1 ) {
            print "Test successful, match found in original pattern.\n";
        } else {
            print "Test failed, you screwed something up!\n";
        }
    } else {
        print "Hmmm, pattern '$match' wasn't found in '$pattern'?\n";
    }
} else {
    print "Dang, no match was found!\n";
}
</code></pre>

<p>I'm not certain if the elimination of back-tracking here would outweigh the performance hit of the reversing.  I guess it would depend greatly on the sizes of both the input string and the length of what could possibly match.</p>

<pre><code>$&gt; perl ./search.pl
FOUND ...
0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
MKTSGNQDEILVIRKGWLTINNIGIMKGGSKEYWFVLTAENLSWYKDDEEKEKKYMLSVDNLKLRDVEKGFMSSKHIFAL
                                                     KYMLSVDNLKLR
Found pattern 'KYMLSVDNLKLR' starting at position '53' and ending at position '64'
Test successful, match found in original pattern.
</code></pre>

<p>I apologize to those that don't understand why I started at zero.</p>

<p>And a bit more real world example - which will find interwoven matches.</p>

<pre><code>#!/usr/bin/perl
use strict;
use warnings;
# NOTE THE INPUT WAS MODIFIED FROM OP
my $input = "MKTSGNQDEILVIRKKRKRRGWKLTINNIRGRIMRGRKGGSKEYWFVLTAENLSWYKDDEEKEKKYMLSVDNLKLRDVEKGFMSSKHIFALKGR";

my $rstart = length $input;
my( $match, $start, $end ) = rsearch( $input, "R.[KR].+?K" );
while( $match ) {
    print "Found matching pattern '$match' starting at offset '$start' and ending at offset $end\n";
    $input = substr $input, 0, $end;
    ( $match, $start, $end ) = rsearch( $input, "R.[KR].+?K" );
}
exit(0);

sub rsearch {
    my( $input, $pattern ) = @_;
    my $reverse = reverse $input;

    if( $reverse =~ /($pattern)/ ) {
        my $length = length $reverse;
        $match = reverse $1;
        $start = $length-$+[0];
        $end   = $length-$-[0]-1;
        return( $match, $start, $end );
    }

    return( undef );
}

perl ./search.pl
Found matching pattern 'KHIFALKGR' starting at offset '85' and ending at offset 93
Found matching pattern 'KYMLSVDNLKLR' starting at offset '64' and ending at offset 75 
Found matching pattern 'KLTINNIRGRIMRGR' starting at offset '22' and ending at offset 36
Found matching pattern 'KLTINNIRGR' starting at offset '22' and ending at offset 31
Found matching pattern 'KRKRR' starting at offset '15' and ending at offset 19 
Found matching pattern 'KKRKR' starting at offset '14' and ending at offset 18
Found matching pattern 'KTSGNQDEILVIRKKR' starting at offset '1' and ending at offset 16
</code></pre>

python perl