Поиск вырожденных последовательностей в структурах ДНК с использованием регулярных выражений
Есть задачи для сервера - искать определенные последовательности в структуре ДНК. Они ставятся по-разному: иногда нужно найти ближайшую последовательность, иногда - все возможные, но чаще всего - найти первую и последнюю.
Если упростить, то есть длинная строка (не менее 8 тысяч символов, алфавит - A, G, T, C) и короткие (не более 12 символов) строки, которые нужно искать. Если строка не вырождена (пример: AACGTT), то задача проста - strpos() и strrpos() дают нормальный по скорости результат, а, главное, - сам результат.
Но если строка вырождена, например, AAWWTT, где W - это C или G, или ещё хуже - CCN(7)GG, где N(7) - это 7 любых символов A, G, T или С, то, как я понимаю, проще всего идти через, например, preg_match_all().
$dna = "AGTC......GTC"; //ДНК-последовательность, длинная строка, берётся из базы, в ней практически гарантированно есть наши искомые строки
$pattern1 = "AA(C|G){2}TT"; // AAWWTT
$pattern2 = "CC.{7}GG"; // CCN(7)GG
$matches = array(); // тут будут результаты
теперь, если просто запустить
if (preg_match_all($pattern1,$ldna,$matches,PREG_OFFSET_CAPTURE) === false)
// PREG_OFFSET_CAPTURE используем, чтобы получить позиции
{
// не нашли - обрабатываем ситуацию, она редка
}
else {
$k1 = $matches[count($matches)-1][1];
}
то имеем две ошибки: "Undefined offset" - это, видимо, из-за того, что массив $matches у нас пуст, поэтому count() к нему неприменимо
и "preg_match_all(): Delimiter must not be alphanumeric or backslash" - а вот с этой ошибкой я не могу разобраться. Я неправильно использую preg_match_all()? Или я так и не научился строить регулярные выражения?
Ответы (1 шт):
паттерн заключается в разделители. обычно это /. То есть /AA(C|G){2}TT/.
Если вам группы захвата сами не нужны, и достаточно будет поиска позиции вхождения, то группы захвата мб не стоит писать. либо использовать non-capturing.
$pattern1 = "/AA([CG]{2})TT/"; // AAWWTT
$pattern2 = "/CC([AGTC]{7})GG/"; // CCN(7)GG
точка используется как любой символ. поскольку ваш алфавит ограничен (пусть и других в строке не встретится), возможно,будет более эффективно использовать не .{7} а [AGTC]{7}, но этот вопрос лучше проверить на практике.
что касается первой ошибки, то сделайте print_r($matches) чтобы уточнить по правильным ли индексам обращаетесь.