<p>The <code>*</code> character has a special meaning in regular expressions, it means "0 or more". So when you write <code>{6,}*</code>, the regex engine tries to apply the "0 or more" to the <code>{6,*}</code> and gets confused:</p>

<pre><code>Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  File "/usr/lib/python3.6/re.py", line 222, in findall
    return _compile(pattern, flags).findall(string)
  File "/usr/lib/python3.6/re.py", line 301, in _compile
    p = sre_compile.compile(pattern, flags)
  File "/usr/lib/python3.6/sre_compile.py", line 562, in compile
    p = sre_parse.parse(p, flags)
  File "/usr/lib/python3.6/sre_parse.py", line 855, in parse
    p = _parse_sub(source, pattern, flags &amp; SRE_FLAG_VERBOSE, 0)
  File "/usr/lib/python3.6/sre_parse.py", line 416, in _parse_sub
    not nested and not items))
  File "/usr/lib/python3.6/sre_parse.py", line 619, in _parse
    source.tell() - here + len(this))
sre_constants.error: multiple repeat at position 10
</code></pre>

<p>In order to use special characters literally, as simple strings, you need to escape them by adding a <code>\</code> before them. So try:</p>

<pre class="lang-python prettyprint-override"><code>import re
myprotein = "&gt;Contig_1 1FFPMPQ*CCLFSSSYLPA*AIMVTGSCQTLVQDKV*CLASCHVMIPPCVFHPIYPLFTWSPLHPIISGCF*AVCMCSWIHALFVEIILSWSLSLPFTFEISSD"
protein = re.findall('M[A-Z]{6,}\*',myprotein)
print(protein)
['MVTGSCQTLVQDKV*', 'MIPPCVFHPIYPLFTWSPLHPIISGCF*']
</code></pre>

<hr>

<p>To get the output you asked for while reading from a file, you can do:</p>

<pre><code>import sys
import re

proteinFile = sys.argv[1]

with open(proteinFile, 'r') as f:
    for line in f:
        ## Split the long input line into the list 'sequences'
        sequences = line.rstrip('\n').split('&gt;')

        for i, k in list(enumerate(sequences)):
            ## Skip the first element which will be empty.
            ## there must be a pythonic way of doing this, but I'm
            ## a Perl hacker, so I don't know it.             
            if len(k) == 0:
                continue

            seqName, seq = k.split(' ')
            ## Get the frame
            frame = seq[0]
            ## Remove the frame from the sequence
            seq = seq[1:]
            # cleave sequence
            peptides = re.findall(r'(M[A-Z]{6,}\*)', seq)

            for idx, peptide in enumerate(peptides):
                print("&gt;%s.%s.%d\n%s" % (seqName, frame, idx+1, peptide) )
</code></pre>

CC BY-SA 4.0
2018-05-01T15:45:54.247Z
2018-05-02T14:38:57.300Z
2018-05-02T14:38:57.300Z
terdon
<p>I have a file with protein sequences, all on a single line, like this:</p>

<pre><code>&gt;Contig_1 1FFPMPQ*CCLFSSSYLPA*AIMVTGSCQTLVQDKV*CLASCHVMIPPCVFHPIYPLFTWSPLHPIISGCF*AVCMCSWIHALFVEIILSWSLSLPFTFEISSD&gt;Contig_2 1FFPCHNSVVYFLLLICLLKPLWSQGVVRHWYRTRCDAWLAVML*YLHVSFIPSIHFLLGRLCTLLYLDVFELYACAAGFMPCLLR*FSLGHSLFLLPLKFPATVKFFSLLGQIMNNISLMNDLQTGEKLQETH*EVEDKSALLVSIIESRCCVTLQPQDFSN*HLGKL*KSVGQKLK*VNDQITY*
</code></pre>

<p>I want to print all sequences between an <code>M</code> residue and a <code>*</code> that are at least 6 residues long, and I would like the output like this:</p>

<pre><code>&gt;contig_1.1.1 
M.......*
&gt;contig_1.1.2 
M........*
&gt;contig_2.1.1 
M............*
&gt;contig_2.1.2 
M......*
</code></pre>

<p>Where the first number after the underscore is the number found in as the first character of the sequence (it is the reading frame) and the second number is the sequence number. and the last number is the fragment number. So, since the 1st sequence starts with;</p>

<pre><code>&gt;Contig_1 1FFPMPQ
</code></pre>

<p>The name will be <code>&gt;Contig_1.1</code> and each fragment found will be <code>&gt;Contig_1.1.1</code>, <code>&gt;Contig_1.1.2</code>, ... , <code>&gt;Contig_1.1.N</code>. </p>

<p>After implementing the suggestion in the answer below and escaping the <code>*</code> in my regular expression, my current code is:</p>

<pre><code>import sys
import re

myprotein = "&gt;Contig_1 1FFPMPQ*CCLFSSSYLPA*AIMVTGSCQTLVQDKV*CLASCHVMIPPCVFHPIYPLFTWSPLHPIISGCF*AVCMCSWIHALFVEIILSWSLSLPFTFEISSD&gt;Contig_2 1FFPCHNSVVYFLLLICLLKPLWSQGVVRHWYRTRCDAWLAVML*YLHVSFIPSIHFLLGRLCTLLYLDVFELYACAAGFMPCLLR*FSLGHSLFLLPLKFPATVKFFSLLGQIMNNISLMNDLQTGEKLQETH*EVEDKSALLVSIIESRCCVTLQPQDFSN*HLGKL*KSVGQKLK*VNDQITY*"
# parse record
my_protein = []
for line in myprotein:
    if not line.startswith('&gt;'):
        my_protein.append(line)
    else:
        header = line

# build sequence
my_pro = ''.join(my_protein)

# cleave sequence                                                                                                                                                                                                                                                        
peptides = re.findall(r'(M[A-Z]{6,}\*)', my_pro)

# build a formatted list
records = ["%sNo.%d\n%s\n" % (header, idx + 1, fragment) for idx, fragment in     enumerate(peptides)]

# print list
for record in records:
    sys.stdout.write("%s" % (record))
</code></pre>

<p>And it prints:</p>

<pre><code> &gt;No.1
 MVTGSCQTLVQDKV*
 &gt;No.2
 MIPPCVFHPIYPLFTWSPLHPIISGCF*
 &gt;No.3
 MNNISLMNDLQTGEKLQETH*
</code></pre>

<p>How can I change this to get my desired output format?</p>

CC BY-SA 3.0
2018-05-01T15:01:37.870Z
re.findall('M[A-Z]{6,}\*', seq)
heathobrien
CC BY-SA 3.0
2018-05-01T15:24:28.697Z
My apologies. the back-slash in my code got stripped for some reason. Try `re.findall('M[A-Z]{6,}\*', seq)`
heathobrien
CC BY-SA 3.0
2018-05-01T15:47:00.920Z
Hi and welcome to the site! When posting this sort of question, please always include the errors you get. Telling us "this doesn't work" is really not very helpful, it is always better to explain how it fails.
terdon
CC BY-SA 3.0
2018-05-01T16:30:19.357Z
Sorry for posting like that I just update my question so it would be great if you could help. Thanks
Nadecho Holme Attaveesin
<fasta><python>
Finding proteins in a sequence
# Finding proteins in a sequence

(Asked by: username_0 on 2018-05-01)

I have a file with protein sequences, all on a single line, like this:
>Contig_1 1FFPMPQ*CCLFSSSYLPA*AIMVTGSCQTLVQDKV*CLASCHVMIPPCVFHPIYPLFTWSPLHPIISGCF*AVCMCSWIHALFVEIILSWSLSLPFTFEISSD>Contig_2 1FFPCHNSVVYFLLLICLLKPLWSQGVVRHWYRTRCDAWLAVML*YLHVSFIPSIHFLLGRLCTLLYLDVFELYACAAGFMPCLLR*FSLGHSLFLLPLKFPATVKFFSLLGQIMNNISLMNDLQTGEKLQETH*EVEDKSALLVSIIESRCCVTLQPQDFSN*HLGKL*KSVGQKLK*VNDQITY*

I want to print all sequences between an M residue and a * that are at least 6 residues long, and I would like the output like this:
>contig_1.1.1 
M.......*
>contig_1.1.2 
M........*
>contig_2.1.1 
M............*
>contig_2.1.2 
M......*

Where the first number after the underscore is the number found in as the first character of the sequence (it is the reading frame) and the second number is the sequence number. and the last number is the fragment number. So, since the 1st sequence starts with;
>Contig_1 1FFPMPQ

The name will be >Contig_1.1 and each fragment found will be >Contig_1.1.1, >Contig_1.1.2, ... , >Contig_1.1.N. 
After implementing the suggestion in the answer below and escaping the * in my regular expression, my current code is:
import sys
import re

myprotein = ">Contig_1 1FFPMPQ*CCLFSSSYLPA*AIMVTGSCQTLVQDKV*CLASCHVMIPPCVFHPIYPLFTWSPLHPIISGCF*AVCMCSWIHALFVEIILSWSLSLPFTFEISSD>Contig_2 1FFPCHNSVVYFLLLICLLKPLWSQGVVRHWYRTRCDAWLAVML*YLHVSFIPSIHFLLGRLCTLLYLDVFELYACAAGFMPCLLR*FSLGHSLFLLPLKFPATVKFFSLLGQIMNNISLMNDLQTGEKLQETH*EVEDKSALLVSIIESRCCVTLQPQDFSN*HLGKL*KSVGQKLK*VNDQITY*"
# parse record
my_protein = []
for line in myprotein:
    if not line.startswith('>'):
        my_protein.append(line)
    else:
        header = line

# build sequence
my_pro = ''.join(my_protein)

# cleave sequence                                                                                                                                                                                                                                                        
peptides = re.findall(r'(M[A-Z]{6,}\*)', my_pro)

# build a formatted list
records = ["%sNo.%d\n%s\n" % (header, idx + 1, fragment) for idx, fragment in     enumerate(peptides)]

# print list
for record in records:
    sys.stdout.write("%s" % (record))

And it prints:
 >No.1
 MVTGSCQTLVQDKV*
 >No.2
 MIPPCVFHPIYPLFTWSPLHPIISGCF*
 >No.3
 MNNISLMNDLQTGEKLQETH*

How can I change this to get my desired output format?

**Tags:** fasta, python
> **Comments:**
> **username_1**: re.findall('M[A-Z]{6,}\*', seq)  
> **username_1**: My apologies. the back-slash in my code got stripped for some reason. Try `re.findall('M[A-Z]{6,}\*', seq)`  
> **username_2**: Hi and welcome to the site! When posting this sort of question, please always include the errors you get. Telling us "this doesn't work" is really not very helpful, it is always better to explain how it fails.  
> **username_0**: Sorry for posting like that I just update my question so it would be great if you could help. Thanks  

---

## 1 answers

### Answer by username_2 on 2018-05-01. Score: 2 | Accepted answer

The * character has a special meaning in regular expressions, it means "0 or more". So when you write {6,}*, the regex engine tries to apply the "0 or more" to the {6,*} and gets confused:
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python3.6/re.py", line 222, in findall
    return _compile(pattern, flags).findall(string)
  File "/usr/lib/python3.6/re.py", line 301, in _compile
    p = sre_compile.compile(pattern, flags)
  File "/usr/lib/python3.6/sre_compile.py", line 562, in compile
    p = sre_parse.parse(p, flags)
  File "/usr/lib/python3.6/sre_parse.py", line 855, in parse
    p = _parse_sub(source, pattern, flags & SRE_FLAG_VERBOSE, 0)
  File "/usr/lib/python3.6/sre_parse.py", line 416, in _parse_sub
    not nested and not items))
  File "/usr/lib/python3.6/sre_parse.py", line 619, in _parse
    source.tell() - here + len(this))
sre_constants.error: multiple repeat at position 10

In order to use special characters literally, as simple strings, you need to escape them by adding a \ before them. So try:
import re
myprotein = ">Contig_1 1FFPMPQ*CCLFSSSYLPA*AIMVTGSCQTLVQDKV*CLASCHVMIPPCVFHPIYPLFTWSPLHPIISGCF*AVCMCSWIHALFVEIILSWSLSLPFTFEISSD"
protein = re.findall('M[A-Z]{6,}\*',myprotein)
print(protein)
['MVTGSCQTLVQDKV*', 'MIPPCVFHPIYPLFTWSPLHPIISGCF*']


To get the output you asked for while reading from a file, you can do:
import sys
import re

proteinFile = sys.argv[1]

with open(proteinFile, 'r') as f:
    for line in f:
        ## Split the long input line into the list 'sequences'
        sequences = line.rstrip('\n').split('>')

        for i, k in list(enumerate(sequences)):
            ## Skip the first element which will be empty.
            ## there must be a pythonic way of doing this, but I'm
            ## a Perl hacker, so I don't know it.             
            if len(k) == 0:
                continue

            seqName, seq = k.split(' ')
            ## Get the frame
            frame = seq[0]
            ## Remove the frame from the sequence
            seq = seq[1:]
            # cleave sequence
            peptides = re.findall(r'(M[A-Z]{6,}\*)', seq)

            for idx, peptide in enumerate(peptides):
                print(">%s.%s.%d\n%s" % (seqName, frame, idx+1, peptide) )


---

