搜索
查看: 1710|回复: 0

实现模糊匹配-高级难度

[复制链接]

634

主题

1182

帖子

4030

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
4030
发表于 2017-1-15 21:20:24 | 显示全部楼层 |阅读模式
新手请勿入坑!
如果要在某个长的字符串匹配一个小的字符串,那么很容易,任何语言都提供了匹配函数,正则匹配嘛,实在不行还可以用shell的grep函数。
但是如果要匹配一个小的字符串,但是不强求完全匹配,可以运行一个错配,或者多个,就是所谓的模糊匹配啦,这个时候,想实现这个需求就很困难了的。
如果我要匹配一个字符串$a="ATTCCGGGAT";那么直接在shell里面grep它即可,写脚本也行$seq =~ /$a/;,但是如果我想查找这个字符串的模糊匹配,允许一个错配的情况,那么就非常多了!这时候简单的匹配已经不能达到目的,但是我们仍然可以用perl强大的正则匹配功能达到目的。
比如,它的匹配模式应该:
/.TTCCGGGAT/
/A.TCCGGGAT/
/AT.CCGGGAT/等等,可以把这些模式都综合起来就是下面这个
$b=(?^?:A(?:T(?:T(?:C(?:C(?:G(?:G(?:G(?:A.|.T)|.AT)|.GAT)|.GGAT)|.GGGAT)|.CGGGAT)|.CCGGGAT)|.TCCGGGAT)|.TTCCGGGAT))
所以我们就应该通过程序来生成这个字符串,然后用
$seq =~ /$b/;来替代$seq =~ /$a/;
而允许两个错配的格式就更复杂了:
(?^?:A(?:T(?:T(?:C(?:C(?:G(?:G(?:G..|.(?:A.|.T))|.(?:G(?:A.|.T)|.AT))|.(?:G(?:G(?:A.|.T)|.AT)|.GAT))|.(?:G(?:G(?:G(?:A.|.T)|.AT)|.GAT)|.GGAT))|.(?:C(?:G(?:G(?:G(?:A.|.T)|.AT)|.GAT)|.GGAT)|.GGGAT))|.(?:C(?:C(?:G(?:G(?:G(?:A.|.T)|.AT)|.GAT)|.GGAT)|.GGGAT)|.CGGGAT))|.(?:T(?:C(?:C(?:G(?:G(?:G(?:A.|.T)|.AT)|.GAT)|.GGAT)|.GGGAT)|.CGGGAT)|.CCGGGAT))|.(?:T(?:T(?:C(?:C(?:G(?:G(?:G(?:A.|.T)|.AT)|.GAT)|.GGAT)|.GGGAT)|.CGGGAT)|.CCGGGAT)|.TCCGGGAT)))


我用perl实现如下:
[Perl] 纯文本查看 复制代码
$a="ATTCCGGGAT";
$one_match=fuzzy_pattern($a,1);
print "$one_match\n";

sub fuzzy_pattern {
my ($original_pattern, $mismatches_allowed) = @_;
$mismatches_allowed >= 0
or die "Number of mismatches must be greater than or equal to zero\n";
my $new_pattern = make_approximate($original_pattern, $mismatches_allowed);
return qr/$new_pattern/;
}
sub make_approximate {
my ($pattern, $mismatches_allowed) = @_;
if ($mismatches_allowed == 0) { return $pattern }
elsif (length($pattern) <= $mismatches_allowed)
{ $pattern =~ tr/ACTG/./; return $pattern }
else {
my ($first, $rest) = $pattern =~ /^(.)(.*)/;
my $after_match = make_approximate($rest, $mismatches_allowed);
if ($first =~ /[ACGT]/) {
my $after_miss = make_approximate($rest, $mismatches_allowed-1);
return "(?:$first$after_match|.$after_miss)";
}
else { return "$first$after_match" }
}
}


只需要控制$one_match=fuzzy_pattern($a,1);里面的参数即可控制自己想要的匹配情况。
然后把生成的匹配模式用了进行序列匹配$seq =~ /$one_mismatch/;
这个程序的重点就是解析需要生成的匹配字符串规则,然后用递归来生成这个匹配字符串。
这种匹配,在引物搜索特别有用







上一篇:把含有简并碱基的引物序列还原成多条序列-高级难度
下一篇:fastq数据perl脚本过滤
你这个问题很复杂,需要打赏,请点击 http://www.bio-info-trainee.com/donate 进行打赏,谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|生信技能树 ( 粤ICP备15016384号  

GMT+8, 2019-10-14 22:24 , Processed in 0.032252 second(s), 28 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.