为了账号安全,请及时绑定邮箱和手机立即绑定

正则表达式 - 在给定数量的 3 个字母序列之后,如何匹配特定的 3 个字母序列?

正则表达式 - 在给定数量的 3 个字母序列之后,如何匹配特定的 3 个字母序列?

慕慕森 2022-05-26 15:35:17
我正在学习遗传学,并且想知道如何获取一些 DNA 数据的第 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任何帮助都会很棒!我把头发拉出来
查看完整描述

3 回答

?
手掌心

TA贡献1942条经验 获得超3个赞

直接匹配数据块的一种方法是补偿数字和空格,同时[acgt]根据您需要的次数匹配和捕获类的三个字符的所有序列。只有最近的捕获可用。与 一起使用的示例preg_match:


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

请参阅正则表达式演示。


在代码中:


$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" } }

OR如果您只想直接匹配目标,则此表达式的变体:


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

\K让引擎记住最后一场比赛的位置,但丢弃那场比赛的内容直到那一刻。请参阅正则表达式演示。


在代码中:


$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" } }

很高兴看到这个问题重新打开。:)


查看完整回答
反对 回复 2022-05-26
?
喵喔喔

TA贡献1735条经验 获得超5个赞

使用 JavaScript,您可以删除空格和数字,string.replace()然后获取第n 个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 。


附录:


我刚刚注意到您似乎正在专门寻找正则表达式解决方案。但是,从我的回答中可以看出,没有必要使用正则表达式来匹配/获取第n 个3 字母序列,我认为使用string.substring()(在 JS 中)或str_split()(在 PHP 中)比使用复杂的正则表达式模式。然而,正则表达式是从数据字符串中删除空格和数字的有效选择。


查看完整回答
反对 回复 2022-05-26
?
FFIVE

TA贡献1797条经验 获得超6个赞

一种方法是匹配模式的 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']));

}


查看完整回答
反对 回复 2022-05-26
  • 3 回答
  • 0 关注
  • 180 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信