Regex - Как сопоставить заданную c 3 буквенную последовательность после заданного количества 3 буквенных последовательностей? - PullRequest
1 голос
/ 21 марта 2020

Я изучаю генетику, и мне было интересно, как я могу получить 248-ю 3-буквенную последовательность некоторых данных ДНК, я пытаюсь найти выражение регулярного выражения, чтобы соответствовать этому. Блок данных также имеет номера в начале каждой строки, которые должны быть исключены вместе с пробелами, в последовательности должны учитываться только буквы. Обычно каждые 3 буквы считаются одной последовательностью, и я хочу найти 248-ю последовательность. Данные также представлены в строковом формате.

                              atggagga gccgcagtca gatcctagcg tcgagccccc
  241 tctgagtcag gaaacatttt cagacctatg gaaactactt cctgaaaaca acgttctgtc
  301 ccccttgccg tcccaagcaa tggatgattt gatgctgtcc ccggacgata ttgaacaatg
  361 gttcactgaa gacccaggtc cagatgaagc tcccagaatg ccagaggctg ctccccccgt
  421 ggcccctgca ccagcagctc ctacaccggc ggcccctgca ccagccccct cctggcccct
  481 gtcatcttct gtcccttccc agaaaaccta ccagggcagc tacggtttcc gtctgggctt
  541 cttgcattct gggacagcca agtctgtgac ttgcacgtac tcccctgccc tcaacaagat
  601 gttttgccaa ctggccaaga cctgccctgt gcagctgtgg gttgattcca cacccccgcc
  661 cggcacccgc gtccgcgcca tggccatcta caagcagtca cagcacatga cggaggttgt
  721 gaggcgctgc ccccaccatg agcgctgctc agatagcgat ggtctggccc ctcctcagca
  781 tcttatccga gtggaaggaa atttgcgtgt ggagtatttg gatgacagaa acacttttcg
  841 acatagtgtg gtggtgccct atgagccgcc tgaggttggc tctgactgta ccaccatcca
  901 ctacaactac atgtgtaaca gttcctgcat gggcggcatg aaccggaggc ccatcctcac
  961 catcatcaca ctggaagact ccagtggtaa tctactggga cggaacagct ttgaggtgcg
 1021 tgtttgtgcc tgtcctggga gagaccggcg cacagaggaa gagaatctcc gcaagaaagg
 1081 ggagcctcac cacgagctgc ccccagggag cactaagcga gcactgccca acaacaccag
 1141 ctcctctccc cagccaaaga agaaaccact ggatggagaa tatttcaccc ttcagatccg
 1201 tgggcgtgag cgcttcgaga tgttccgaga gctgaatgag gccttggaac tcaaggatgc
 1261 ccaggctggg aaggagccag gggggagcag ggctcactcc agccacctga agtccaaaaa
 1321 gggtcagtct acctcccgcc ataaaaaact catgttcaag acagaagggc ctgactcaga
 1381 ctga

Любая помощь будет фантастической c! Я тяну свои волосы за это

Спасибо :))

Ответы [ 3 ]

1 голос
/ 21 марта 2020

Один из способов прямого сопоставления с вашим блоком данных - это компенсация чисел и пробелов при сопоставлении и захвате всех последовательностей из трех символов класса [acgt] для требуемого количества раз. Будет доступен только самый последний снимок. Пример использования с preg_match:

/\A(?:((?:[\s\d]*[acgt]){3})){248}/m

См. regex demo .

В коде:

$re = '/\A(?:((?:[\s\d]*[acgt]){3})){248}/m';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
var_dump($matches);

Вывод (упрощенный):

array(1) { [0]=> array(2) { [0]=> string(...) " atgg...cgg" [1]=> string(3) "cgg" } }

ИЛИ Вариант этого выражения, если вы хотите напрямую соответствовать только цели:

/\A(?:(?:[\s\d]*[acgt]){3}){247}\K(?:[\s\d]*[acgt]){3}/m

\K заставляет двигатель запоминать положение последний матч, но выбросить содержимое этого матча до этого момента. См. regex demo .

В коде:

$re = '/\A(?:(?:[\s\d]*[acgt]){3}){247}\K(?:[\s\d]*[acgt]){3}/m';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
var_dump($matches);

Вывод:

array(1) { [0]=> array(1) { [0]=> string(3) "cgg" } }

Рад видеть, что этот вопрос вновь открыт. :)

0 голосов
/ 22 марта 2020

Используя JavaScript, , вы можете удалить пробелы и цифры с помощью string.replace(), а затем получить nth 3-буквенную последовательность, например, с помощью string.substring():

const data = `
                              atggagga gccgcagtca gatcctagcg tcgagccccc
  241 tctgagtcag gaaacatttt cagacctatg gaaactactt cctgaaaaca acgttctgtc
  301 ccccttgccg tcccaagcaa tggatgattt gatgctgtcc ccggacgata ttgaacaatg
  361 gttcactgaa gacccaggtc cagatgaagc tcccagaatg ccagaggctg ctccccccgt
  421 ggcccctgca ccagcagctc ctacaccggc ggcccctgca ccagccccct cctggcccct
  481 gtcatcttct gtcccttccc agaaaaccta ccagggcagc tacggtttcc gtctgggctt
  541 cttgcattct gggacagcca agtctgtgac ttgcacgtac tcccctgccc tcaacaagat
  601 gttttgccaa ctggccaaga cctgccctgt gcagctgtgg gttgattcca cacccccgcc
  661 cggcacccgc gtccgcgcca tggccatcta caagcagtca cagcacatga cggaggttgt
  721 gaggcgctgc ccccaccatg agcgctgctc agatagcgat ggtctggccc ctcctcagca
  781 tcttatccga gtggaaggaa atttgcgtgt ggagtatttg gatgacagaa acacttttcg
  841 acatagtgtg gtggtgccct atgagccgcc tgaggttggc tctgactgta ccaccatcca
  901 ctacaactac atgtgtaaca gttcctgcat gggcggcatg aaccggaggc ccatcctcac
  961 catcatcaca ctggaagact ccagtggtaa tctactggga cggaacagct ttgaggtgcg
 1021 tgtttgtgcc tgtcctggga gagaccggcg cacagaggaa gagaatctcc gcaagaaagg
 1081 ggagcctcac cacgagctgc ccccagggag cactaagcga gcactgccca acaacaccag
 1141 ctcctctccc cagccaaaga agaaaccact ggatggagaa tatttcaccc ttcagatccg
 1201 tgggcgtgag cgcttcgaga tgttccgaga gctgaatgag gccttggaac tcaaggatgc
 1261 ccaggctggg aaggagccag gggggagcag ggctcactcc agccacctga agtccaaaaa
 1321 gggtcagtct acctcccgcc ataaaaaact catgttcaag acagaagggc ctgactcaga
 1381 ctga
`

function getNthSequence(n) {
  const sequenceLength = 3
  const startIndex = (n - 1) * sequenceLength

  return data
    .replace(/\s|\d/g, '')
    .substring(startIndex, startIndex + sequenceLength)
}

console.log(getNthSequence(1))
console.log(getNthSequence(2))
console.log(getNthSequence(248))

Используя PHP, , вы можете удалить пробелы и цифры с помощью preg_replace(), а затем разбить строку на массив из 3- буквенные строки с str_split():

<?php

$data = <<<DNA
                              atggagga gccgcagtca gatcctagcg tcgagccccc
  241 tctgagtcag gaaacatttt cagacctatg gaaactactt cctgaaaaca acgttctgtc
  301 ccccttgccg tcccaagcaa tggatgattt gatgctgtcc ccggacgata ttgaacaatg
  ...
DNA;

$sequences = preg_replace('/\s|\d/', '', $data);
$sequences = str_split($sequences, 3);

echo $sequences[0] . PHP_EOL;
echo $sequences[1] . PHP_EOL;
echo $sequences[247];

См. https://3v4l.org/9mpcE для демонстрации.


Добавление:

Я только что заметил, что вы, похоже, специально ищете решение для регулярных выражений. Однако, как видно из моего ответа, нет необходимости использовать регулярное выражение для сопоставления / получения 3-буквенной последовательности nth , и я бы сказал, что используя string.substring() (в JS) или str_split() (в PHP) чище и удобочитаемее, чем использование сложного шаблона регулярных выражений. Тем не менее, регулярное выражение является допустимым выбором для удаления пробелов и чисел из строки данных.

0 голосов
/ 21 марта 2020

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

$pattern = '/
 (?(DEFINE)(?<sequence>(?:[a-z][^a-z]*){3})) # define a pattern for a 3 letter sequence
 (?&sequence){247} # consume 247 occurrences 
 (?<match>(?&sequence)) # match 248th occurrence
/x';

if (preg_match($pattern, $data, $matches)) {
  var_dump(preg_replace('/[^a-z]+/', '', $matches['match']));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...