2014-09-09 3 views
0

Я пишу программу Java, которая ищет последовательность ДНК по 15 символов за раз, нахожу разделы с наибольшим количеством вхождений C и G. Я полагал, что это будет чтобы проверить всю последовательность ДНК для любых областей, где подстрока 15 состоит полностью из C и G, а если они не существуют, поиск подстрок с 14 C и G и 1 A или T. Тогда, если это не приходят, 13 CG и 2 AT и т. д.RegEx на строку для соответствия И соответствие НЕЗАВИСИМОСТЬ порядка

Попытка найти решение для этого регулярного выражения оказалось для меня трудной задачей. Я придумал тестовый пример, используя этот код, но я не могу заставить RegEx работать. Я думаю, что синтаксис может быть неправильным, я никогда не использовал RegExes в Java. Извините за это, я могу, возможно, выяснить синтаксис, мне просто нужна помощь с правильным выражением, которое соответствует правильной вещи.

public class DNAChecker{ 

    public static void main(String []args){ 
     String checkThis= "ggccggccaggccgg"; 

     if (checkThis.matches(“(?=.*[CcGg]{14})(?=.*[AaTt]{1})”)) { 
      System.out.println("This program works."); 
     } else { 
      System.out.println("This program doesn't work."); 
     } 
    } 
} 

Я так понимаю, это и от того, что я видел в соответствующих потоков, если это может быть сделано с помощью регулярных выражений, я получаю по крайней мере близко с этим. Теперь, когда я думаю об этом, я не думаю, что это гарантирует, что общее совпадение составляет 15 символов ... т. Е. Если checkThis был длиной более 15 символов и имел 14 CG и 1 AT total, последовательно это все равно будет правдой. Таким образом, xxxxggccggxxccaggccggxxxxxx будет правдой. Будет ли использовать .contains вместо .matches гарантировать ограничения длины?

Как бы то ни было, если бы однострочный регрессивный регрессивный регистр выглядел быстрее, чем подсчет C и G каждой подстроки? Я еще не взял класс алгоритмов.

Обратите внимание, что эта программа в ее окончательной форме будет принимать строку переменной длины и искать подстроки длиной n, а не 15 каждый раз. (Я знаю, как справиться с этими требованиями, поэтому не нужно рассказывать мне о Scanner или о том, как работают аргументы!) Я просто RegEx noob, пытающийся использовать материал RegEx на уровне Jedi ... если бы вы могли порекомендовать мне книгу чтобы стать волшебником RegExes, тоже было бы радикальным. Большое спасибо за ваши ответы!

+1

Боюсь, что Regex, вероятно, не будет слишком полезен для вас для этой проблемы. Я бы порекомендовал просто подсчитывать количество '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''' '' '' 'вместо –

+0

Что касается информации/учебников по регулярным выражениям, попробуйте этот сайт: [regular-expressions.info] (http: // regular- expressions.info) – Thomas

+0

И [Частые вопросы регулярных выражений переполнения стека] (http://stackoverflow.com/a/22944075/2736496)! – aliteralmind

ответ

2

Regexes - одна из самых соблазнительных особенностей любого языка. Однако только потому, что они классные и сексуальные и выглядят очень мощными, это не значит, что они правильный инструмент. Для чего-то вроде этого достаточно простого состояния машины и, скорее всего, будет намного быстрее. В приведенном ниже коде самая длинная подстрока, содержащая только c и g, и может быть легко адаптирована для хранения нескольких подстрок, добавив их в коллекцию.

String data = "acgtcgcgagagagggggcccataatggg"; 
    int longestPos = 0; 
    int longestLen = 0; 
    int p=-1; 
    for (int i=0; i<data.length(); i++) 
    { 
     char c = data.charAt(i); 
     if (c == 'c' || c == 'g') // Is this the droid you're looking for? 
     { 
      if (p==-1) // Are we not yet in an interesting string? 
       p = i; // If so, save the position of this start of substring. 
     } 
     else // Not a c or g 
     { 
      if (p != -1 && i-p > longestLen) // Are we in an interesting string longer than the previous longest? 
      { 
       longestPos = p;  // Save the starting position 
       longestLen = i-p; // Save the length 
      } 
      p = -1; // We're no longer inside an interesting string 
     } 
    } 

    // Handle the case where the last substring was 'interesting' 
    if (p != -1 && i-p > longestLen) 
    { 
     longestPos = p;  // Save the starting position 
     longestLen = i-p; // Save the length 
    } 

    System.out.printf("Longest string is at position %d for length %d", longestPos, longestLen); 

Для канонический ответ на «давайте использовать регулярное выражение, где он не применяется» см this post

0

Я не совсем уверен, правильно ли я понимаю вашу проблему, поэтому я предполагаю, что вы хотите найдите самую длинную последовательность символов, состоящую из c s и g s, а затем a или t.

Я также предполагаю, что ваша строка ввода содержит только эти символы.

Таким образом, вы можете попробовать и использовать Pattern.compile(regex).matcher(input).find(), чтобы получить все группы, которые подходят. Затем сортируйте их по длине, и вы получите самые длинные последовательности.

Для этого вы можете использовать следующее регулярное выражение: (?i)([cg]+[at]) ((i?) делает регистр выражения нечувствительным).

Пример:

String input = "ccgccgCggatccgCATccggcccgggggtatt"; 

List<String> sequences = new ArrayList<>(); 

//find the sequences 
Matcher m = Pattern.compile("(?i)([cg]+[at])").matcher(input); 
while(m.find()) { 
    sequences.add(m.group().toLowerCase()); 
} 

//sort by descending length 
Collections.sort(sequences, new Comparator<String>() { 
    public int compare(String lhs, String rhs) { 
    //switch arguments for descending sort 
    return Integer.compare(rhs.length(), lhs.length()); 
    } 
}); 

System.out.println(sequences); 

Ouput будет: [ccggcccgggggt, ccgccgcgga, ccgca]

Если вы хотите, чтобы просто позволить определенную длину этих последовательностей, вы должны изменить регулярное выражение:
(?i)(?<=^|[^cg])([cg]{10,15}[at])

Изменения:

(?<=^|[^cg]) означает, что последовательность должна предшествовать начало ввода или что-либо кроме c или g. Чтобы соответствовать частям более длинных последовательностей, то есть gcga из cccgcga, вы просто удалите это из своего регулярного выражения.

[cg]{10,15} означает, что последовательность cs и gs должна быть между 10 и 15 символами, то есть более короткие последовательности не будут сопоставляться, тогда как более длинные последовательности могут быть сопоставлены, если вы не используете (?<=^|[^cg]). Для использования точной длины, например. 15 символов, используйте указанное выше условие и измените это условие на [cg]{15}.

+0

О, как я люблю downvotes без комментариев. ;) – Thomas

Смежные вопросы