2011-05-18 8 views
8

Yani, bir tek-harfli kodlanmış dizide B ya da D tarafından kodlanan proteinler önce parçalayan bir enzim (merakınız için, Asp-N) ile bir protein dizisi sindiriyorum. Gerçek analizim, yakalamalar için String#scan kullanıyor. Ben önceki (.*\b) dizisinin sonunu yakalamak için varRegex Protein Sindirimi

(\w*?)(?=[BD])|(.*\b) 

... aşağıdaki normal ifade doğru sindirmek değil anlamaya çalışıyorum. için:

MTMDKPSQYDKIEAELQDICNDVLELLDSKGDYFRYLSEVASGDN 

Bu gibi bir şey vermelidir: [MTM, DKPSQY, DKIEAELQ, DICN, DVLELL, DSKG, ... ] ancak bunun yerine sırayla her D kaçırır.

Sorun gidermek için http://www.rubular.com kullanıyorum, 1.8.2 üzerinde çalışıyorum, ancak yine de RE REXX'i 1.9.2'de test etmeme rağmen. Sıfır genişliğindeki lookahead iddialarının yakutun her iki versiyonunda desteklendiği benim anlayışım. Regex'imle neyi yanlış yapıyorum?

+0

Hangi yöntemi kullanıyorsunuz? "String # scan", "String # split" veya başka bir şey var mı? –

+3

+1 Ne harika bir soru. Elde ettiğin sonuçları beklemedim ve daha fazla analiz bana normal ifadenin tekrarlanan sıfır genişlikli eşleşmeleriyle ilgili bir şey öğretti. – Phrogz

+0

"B veya D tarafından kodlanan proteinlerden önce ayrılan" ifadenizle biraz kafam karışmış durumda. Anladığım kadarıyla, ** B ** ** ya da N (**) 'nin kalıntı ya da Asn olup olmadığı bilinmeyen tek harfli koddur? Asp-N Asn'den önce ayrılabilir mi? – tomd

cevap

3

bunu desteklemek için basit yolu sıfır genişlikli lookahead üzerinde bölmek olduğunu verir:

sizin çözümde yanlış gittiğini ne olduğu anlamak için
s = "MTMDKPSQYDKIEAELQDICNDVLELLDSKG" 
p s.split /(?=[BD])/ 
#=> ["MTM", "DKPSQY", "DKIEAELQ", "DICN", "DVLELL", "DSKG"] 

, ilk önce regex'inize bakacak olana karşı bakalım:

p s.scan(/.*?(?=[BD]|$)/) 
#=> ["MTM", "", "KPSQY", "", "KIEAELQ", "", "ICN", "", "VLELL", "", "SKG", ""] 

p s.scan(/.+?(?=[BD]|$)/) 
#=> ["MTM", "DKPSQY", "DKIEAELQ", "DICN", "DVLELL", "DSKG"] 

Sorun, sıfır karakterleri yakalayabilmeniz ve yine de sıfır genişlikli göz atma noktanızla eşleşebilmeniz durumunda, tarama işaretçisini ilerletmeden başarılı olmanızdır. en basit-ama-benzer bir test durumu bakalım:

s = "abcd" 
p s.scan //  # Match any position, without advancing 
#=> ["", "", "", "", ""] 

p s.scan /(?=.)/ # Anywhere that is followed by a character, without advancing 
#=> ["", "", "", ""] 

String#scan bir naif uygulaması defalarca ilk karakterin önüne işaretçisi ile eşleşen, sonsuz döngü içinde takılıp olabilir. İşaretçiyi ilerletmeden bir eşleşme gerçekleştiğinde, algoritmanın işaretçiyi bir karakter tarafından zorla ilerletir.

  • o zaman karakter işaretçisi hareket ettirmeden, sağ B veya D öncesinde sıfır genişlikli pozisyonunu maçları Önce bir B veya D'ye kadar olan tüm karakterleri ile eşleşen

    1. ,: Bu durumda sonuçlarını açıklıyor Sonuç olarak, algoritma işaretçiyi B veya D'yi geçecek şekilde hareket ettirir ve bundan sonra devam eder.
    +0

    Belki de diğer cevaplar işe yarayacak gibi, basitleştirmeliyim, ama aradığım şey bu: Anlama! Düzenli İfademin neden kırıldığını açıkladığın için teşekkür ederim! – Ryanmt

    +0

    @Ryanmt Yardım edebileceğime sevindim. Ayrıca, daha basit bölünmüş tabanlı bir çözüm yerine bunu kullanmak isterseniz, sekansın sonunu yakalamanın daha kolay bir yolunu göstermek için düzenli ifademi değiştirdim. – Phrogz

    +0

    Ah. Bunu okudum ama sorunuma uygulamamıştım. Teşekkürler! – Ryanmt

    9

    Temel olarak, her B veya D'den önce dizgeyi kesmek mi istiyorsunuz?

    "...".split(/(?=[BD])/) 
    

    size

    ["MTM", "DKPSQY", "DKIEAELQ", "DICN", "DVLELL", "DSKG", "DYFRYLSEVASG", "DN"] 
    
    +0

    Harika cevap ve temizleyin. Teşekkürler! – Ryanmt