views:

311

answers:

4

Does a regular expression exist for (theoretical) tryptic cleavage of protein sequences? The cleavage rule for trypsin is: after R or K, but not before P.

Example:

Cleavage of the sequence VGTKCCTKPESERMPCTEDYLSLILNR should result in these 3 sequences (peptides):

 VGTK
 CCTKPESER
 MPCTEDYLSLILNR

Note that there is no cleavage after K in the second peptide (because P comes after K).

In Perl (it could just as well have been in C#, Python or Ruby):

  my $seq = 'VGTRCCTKPESERMPCTEDYLSLILNR';
  my @peptides = split /someRegularExpression/, $seq;

I have used this work-around (where a cut marker, =, is first inserted in the sequence and removed again if P is immediately after the cut maker):

  my $seq      = 'VGTRCCTKPESERMPCTEDYLSLILNR';
  $seq         =~ s/([RK])/$1=/g; #Main cut rule.
  $seq         =~ s/=P/P/g;       #The exception.
  my @peptides = split( /=/, $seq);

But this requires modification to a string that can potentially be very long and there can be millions of sequences. Is there a way where a regular expression can be used with split? If yes, what would the regular expression be?


Test platform: Windows XP 64 bit. ActivePerl 64 bit. From perl -v: v5.10.0 built for MSWin32-x64-multi-thread.

+5  A: 

You could use look-around assertions to exclude that cases. Something like this should work:

split(/(?<=[RK](?!P))/, $seq)
Gumbo
Apologies if I am wrong, but wouldn't this end up splitting before the R/K in the sequence, rather than after?
Anon.
Indeed, this won't work. The RK needs to be a positive lookbehind (?<=...)
gab
@Anon and gab: yes, it results in cut before; 4 peptides: VGT, RCCTKPESE, RMPCTEDYLSLILN and R
Peter Mortensen
+3  A: 

You can use lookaheads and lookbehinds to match this stuff while still getting the correct position.

/(?<=[RK])(?!P)/

Should end up splitting on a point after an R or K that is not followed by a P.

Anon.
`/(?<[RK])(?=[^P])/` avoids splitting off an empty string at the end
ysth
For both: not accepted at compile time. For ysth's: "Sequence (?<[...) not recognized in regex; marked by <-- HERE in m/(?<[ <-- HERE RK])(?=[^P])/". I have updated the question with platform information.
Peter Mortensen
Sorry, I messed up the positive lookbehind syntax. It should be `(?<=...`. I'll correct it.
Anon.
and I copied his error :( - it should be `/(?<=[RK])(?=[^P])/` - but since split by default removes trailing empty fields, it would only matter if you were splitting a fixed number of fields or using the regex with something other than split.
ysth
Yes, both now work as expected.
Peter Mortensen
A: 

In Python you can use the finditer method to return non-overlapping pattern matches including start and span information. You can then store the string offsets instead of rebuilding the string.

Joe Koberg
perl can do this as well. See http://stackoverflow.com/questions/467800/is-there-a-perl-equivalent-of-pythons-re-findall-re-finditer-iterative-regex-re
snoopy
+13  A: 

You indeed need to use the combination of a positive lookbehind and a negative lookahead. The correct (Perl) syntax is as follows:

my @peptides = split(/(?!P)(?<=[RK])/, $seq);
gab
Sure you mean negative lookahead and positive lookbehind.
Anon.
Yes, this works.
Peter Mortensen