Perl入门


根据网易云课程整理,禁转

简介

时间:Larry Wall 1987
Practical Extraction and Reporting Language
perl第三方包网站
学习书籍:Perl 语言入门(小骆驼)
生信领域需要对perl进行学习
perl环境搭建:eclipse生信编程环境搭建

标量

数字

整数
浮点数

数字操作

加减乘除 + - * /
求余数% 求幂**

字符串

单引号/双引号引起来的字符为字符串
perl中单引号与双引号区别

字符串中的转义字符\

\t 表示tab空白
\n 表示换行符

print "one day\n";
print "one \"day\"\n"; #转义双引号
print "one \\day\n";  #转义反斜杠
字符串的特殊表示q()/qq()

使代码更清晰

qq(string in "qq") #="string in \"qq\""
q(string in 'q') #='string in \'q\''

*()可换乘<>,{},[]等配对字符,如qq/string in "qq"/

字符串的操作
  • 字符串连接 .
  • 获得字符串长度 length()
  • 字符串截取. substr()
print "hello"." word"."\n"; #hello world
print length("hello");
print substr("ATCCGG",3,3); #从第三个字符开始取三个字符
print substr("ATCCGG",3,-3); #去掉开头和结尾三个字符
字符串和数字转换

perl在某些情况下会自动转换print 12+"12"

split 按指定字符分隔字符串
my $str = "aa:bb:cc";
my @split_str = split (/:/, $str, 2);
#split(/分隔符/, 变量名,分隔成几个元素),返回数组
print "@split_str";
chomp 去换行符
my $str = "aa:bb:cc\n";
chomp $str;

标量变量

变量是存储在内存中的数据,创建一个变量就会在内存上开辟一个空间
标量变量用 $ ,声明变量用 my my$name;
Perl 变量命名规则

变量的赋值

变量赋值符号 =

my$number=10;
my$number1=$number+20;

my$name="abc\n";
print $name;
my$love="I love " . $name;

变量创建不赋值,默认为undef
my$number=undef; / my$number;
注:空字符串不等于未定义

  • 为什么要使用变量?
    如果需要对变量内容进行修改只需要修改一处代码
  • 为什么要使用my?
    使用my会有重复变量名提示
字符串中变量内插

只在双引号中支持,单引号中不支持

my $name="abc";
print "this is $name\n";  #=print "this is " . $name . "\n"

如何避免变量内插变量名歧义

my $name = "abc";
my $names = "efg";
print "this is $names\n";  # this is efg
print "this is ${name}s\n";  #this is abcs

判断语句

判断操作符
比较数字字符串
相等==eq
不等!=ne
小于<lt
大于>gt
小于/等于<=le
大于/等于>=ge

布尔表达式:
35 ==35.0 #返回真
"35" eq "35.0" #返回假(当作字符串比较)

if判断语句
my $num = 10;
if($num > 20){
	#if true
	print "$num is larger than 20\n";
}
print "\$num is $num\n";

注意perl对于字符串和数字的自动转换
固定为false: 0 / undef / “”

if …else语句
my $var = 0;
if($var){
	print "$var is true\n";
}else{
	print "$var is false\n";
}
if…elsif语句
my $ num =100;
if ($num > 200){
	print "\$num > 200\n";
}elsif($num >100){
	print "\$num >100\n";
}else{
	print "\$num is very small\n";
}
if多重判断
my $num = 100;
if($num > 100 and $num < 200){
	print "\$num >100 and \$num <200\n";
}
if(($num > 100 || $num >80) and $num < 200){
	print "\$num >80 and \$num <200\n";
}

多个条件同时为真:and &&
多个条件有一个为真:or ||
多个条件时,通过()来表明判断顺序

列表和数组

列表(list):标量的有序集合
数组(array):存储列表的变量
数组创建:@ my @arry = (22,"perl")

列表

列表产生
  • 列表用()产生
    (1,2,3) 包含三个数字的列表
    (1,2,3,) 同上,末尾逗号被忽略
    (1,"perl") 标量类型可混合
    () 空列表

  • 产生连续的数字列表…
    (1..5) (1,2,3,4,5)
    (1.5..5.7) 同上,小数部分被忽略
    (1,5..8) (1,5,6,7,8)
    ($m..$n) 可以用变量表示,范围由 m 和 m和 mn当前的值来决定

列表赋值给变量

my ($ID, $gene, $num) = ("ID1", "ATTCG", undef);
如果列表中元素数量大于变量数量,列表中多余元素被忽略

列表赋值给数组
  • 列表可以连接两个数组
  • 使用qw列表,可以省略 “” 和 ,
my @giant = 1..1000;              #包含1000个元素的列表
my @merge = (@giant, @giant);       #连接两个数组
my $name = "perl";
my @merge1 = (@giant, $name, "perl", @giant)  #可混搭
my @tiny = ()                                 #空列表
my @rocks = qw(bedrock slate lava) #可以省略逗号和引号

数组操作

  • 打印数组
    print @rocks; 打印时不会在数组的元素间加空格
    print "@rocks\n"; 打印时会在数组的元素间加空格,即perl支持字符串中数组内插
  • 连接数组
    my @merge = (@giant, @giant);
为数组元素添加指定分隔符 join
my @rocks = qw(bedrock slate lava)
my $join_string = join("\t", @rocks);
print "join: $join_string\n";   #join: bedrock	slate	lava
print join("-", @rocks)."\n";  #bedrock-slate-lava
访问或获取数组的元素
  • 索引法 (索引从0开始)
  • 取出一个元素:$array[0] 标量
  • 特殊变量:$#array 数组最后一个元素的索引值
  • 最后一个元素:$array[$#array]
  • 取出多个元素 :@array[0..2] 数组
my @names = (0..10);
print "@names[2..5]"; #2 3 4 5
print "@names[(2,4,6)]\n"; #2 4 6
print "@names[2,4,6]\n"; #2 4 6
数组结尾添加和减少元素

添加元素push
取出元素pop,取出结尾的元素后原数组会少一个元素

my @names = (0..10);

pop(@names); #直接扔掉最后一个元素
pop @names; #省略括号效果同上
my $last = pop(@names);
print "\$last is $last\n";  #8

push(@names, 100); #在数组后追加100
push @names, 100;  #效果同上
push @names, 1..3; #可以追加列表
my @num = 1..5;
push @names, @num; #可以追加数组,即实现数组合并
数组开头添加和减少元素

添加元素unshift
取出元素shift

my @names = (0..10);

shift @names; #去掉0
my @num = 1..5;
unshift @names, @num; #可以在开头添加数组,即实现数组合并

批量获得数组的值
  • for方法依次获取数组的元素
my @names = (0..10);

for(my $i = 0; $i < @names; $i ++){
	print "$i : $names[$i]\n";
}
my @names = (0..10);

#按数组元素顺序直接循环数组本身
for my $value(@names){
	print "value : $value\n";
}
#元素为数字时的循环方法
for my $i(0..$#names){
	print "value: $names[$i]\n";
}
#同时输出索引
my $i=0;
for my $value(@names){
	$i++;
	print"$i: $value\n";
}
数组排序方法sort

排序特殊变量$a, $b
按字符排序,用cmp

my @languages = qw(perl python r java);
my @languages_sorted = sort {$a cmp $b} @languages;
print "@languages_sorted\n";

按数值排序用<=>

my @names = (3,7,32,1,5,16);
my @names_sorted = sort {$a <=> $b} @names;
print "@names_sorted\n";

如果数组中即有字符串又有数字,用cmp
倒序:sort {$b cmp $a} @languages

标量上下文和列表上下文 context

perl最独特的特性就在于,它的代码对于上下文是敏感的。
每个表达式要么在scalar上下文中求值,要么在列表上下文求值

my $scalar = "mendeleev";     #赋值,标量上下文
my @array = ("alpha","bata","gamma","pie");   #列表上下文
my ($perl,$python,$R) = ("perl","python","R");   #列表上下文

my $perl = ("perl","python","R");   #标量上下文,将列表的长度赋值给标量
print "$perl\n";   #3
my ($perl) = ("perl","python","R");   #列表上下文
print "$perl\n";   #perl     #把第一个元素赋值给标量

列表上下文用于数组赋值/标量批量赋值
强制标量上下文获得数组长度

@name = qw(perl R python shell);
print @name,"/n";       #perlRpythonshell
print scalar @name,"/n";    #3 强制标量上下文

获得字符串和数组长度

my @names = (0..10);
my $num = @names;
print "$num\n";

my $name = "perl";
print length($name)."\n";

哈希变量HASH

数组:索引-值,有顺序
哈希:键keys-值values(键不能重复,值可以重复),没有顺序

哈希创建 %
my %last_name = ("zhangsan"=>"zhang", "lisi"=>"li", "wangwu"=>"wang");
my %last_name = (
	"zhangsan"=>"zhang", 
	"lisi"=>"li", 
	"wangwu"=>"wang"
);
my %last_name = ();  #空哈希
访问哈希的值

$last_name{"zhangsan"};
注意:$ {}
访问数组的值:$array[0]/@array[0…3]

向哈希中添加值

$last_name{"zhaosi"} = "zhao";
如果键出现重复,将覆盖该键原来的值

从哈希中删除元素

delete $last_name{"zhaosi"};

查看哈希中值是否存在exist
if (exist $last_name{"zhaosi"}){
	print "value existed: \$last_name{"zhaosi"};
}else{
	print "value not existed: \$last_name{"zhaosi"};
}

为何要用exist判断?
用exist判断,防止代码终止。

哈希函数应用

keys获取哈希所有的键
values获取哈希所有的值
返回列表,注意没有顺序

my %last_name = ("zhangsan"=>"zhang", "lisi"=>"li", "wangwu"=>"wang");
my @my_key = keys%last_name;
my @my_value = values%last_name;
循环哈希的键值对

while获取哈希的键值对

my %last_name = ("zhangsan"=>"zhang", "lisi"=>"li", "wangwu"=>"wang");
while(($k,$v)=each %last_name){
	print "$k => $v \n";
}

foreach获取哈希的键值对

my %last_name = ("zhangsan"=>"zhang", "lisi"=>"li", "wangwu"=>"wang");
for my $k ( keys %last_name){
	my $v = $last_name{$k}
	print "$k => $v \n";
	print "another: $k => $last_name{$k}\n";
}

循环键值对并排序

my %last_name = ("zhangsan"=>"zhang", "lisi"=>"li", "wangwu"=>"wang");
for my $k ( sort {$a cmp $b} keys %last_name){ 
	print "another: $k => $last_name{$k}\n";
}
#{$a cmp $b} 可省略

Perl读取输出文件

读取文件,输出文件open

注意:open打开的是文本文件,或记事本可以打开的文件

open (IN, "<D:/exp.txt") || die "can not open file : D:\\exp.txt";    
# open(文件句柄,文件路径) 
# 注意:如果用反斜杠需要转义,文件路径的<可以省略
open (OUT, ">D:/out.txt") || die "can not file : D:\\out.txt";
# >>追加内容,>覆盖原内容/新建文件

my$line1=<IN>;  #<IN>只读一行,字符串
print OUT $line1 . "\n";

my@lines=<IN>; #列表上下文,每一行为列表的一个元素
print OUT "@lines" ;
#通常不会这么做,占内存

#循环读入数据
while(my $line = <IN>){	
	print OUT $line;
}
close(IN);
close(OUT);
perl特殊变量

perl特殊变量$!:用于存储错误信息
open (IN, "<D:/exp.txt") || die "can not open file $!";

perl特殊变量$_:老地方,在不声明的时候使用的默认变量

open (IN, "<D:/exp.txt") || die "can not open file : D:\\exp.txt";    
open (OUT, ">D:/out.txt") || die "can not file : D:\\out.txt";

#循环读入数据
while(my $line = <IN>){	
	print OUT $line;
}

#循环读入数据,效果同上
while( <IN>){	
	print OUT "$_";
}
close(IN);
close(OUT);

Perl 正则表达式

正则表达式规则

主要应用
  • 查找/匹配 m//(可以简写为//,省略m)
  • 转换 tr///
  • 替换 s///
  • 捕获 ()
    可套用(()()),按照左括号(出现的顺序赋值到变量
    (.*) capture all
  • 计数 捕获全部->标量上下文
#查找匹配
my $bar = "I am a robot. Welcome to robot site.";
if ($bar = ~m/robot/){
	print "matched robot\n";
}else{
	print "did not match robot\n";
}

#转换
#生成DNA序列的反向互补序列
my $DNA = "ATTGGCCAT";
$DNA = ~tr/ATCG/TAGC/;
$DNA = ~tr/A-Z/a-z/;  #大小写转换
$DNA = reverse($DNA); #反向
print $DNA."\n";

#替换
my $z = "I am a robot\n Welcome to Robot site\n robot";
$z = ~s/robot/AAA/; #只对第一个robot进行替换
$z = ~s/robot/AAA/gi; #修饰符g替换全局robot,i忽略大小写
$z = ~s/robot$/AAA/gi;
#铆定行尾,一个字符串行尾只有一个,I am a robot\n Welcome to Robot site\n AAA
$z = ~s/robot$/AAA/gim;
#修饰符m多行模式,可以有多个行尾,I am a AAA\n Welcome to Robot site\n AAA

#捕获
my $f = "0/1:20,6:26:99	0/0:20,5:25:99";
$f = ~/([01]\/[01])/;   #捕获第一个0/1
my $value = $1;
print $value."\n";

#捕获全部0/1,0/0
my $f = "0/1:20,6:26:99	0/0:20,5:25:99";
@gene = ($f = ~/([01]\/[01])/g);   #列表上下文
print "@gene\n";

#捕获+计数
my $f = "0/1:20,6:26:99	0/0:20,5:25:99";
$num = () = $f = ~/([01]\/[01])/g;   #标量上下文
print "$num\n";

#捕获+替换
my $f = "0/1:20,6:26:99	0/1:20,5:25:99";
$f = ~s/([01])\/([01])/$2\/$1/g;   #将所有0/1替换成1/0
print $f."\n";

my $DNA = "AATAAT	AAGCCG";
$DNA = ~s/AA(.)(.)\2\1/GGGG/g; 
#在第一组反斜杠内调用捕获内容可以直接用\1
print $DNA."\n";

引用用法

实现复杂数据的读取和存储

查看引用类型

ref($refname)

字符串引用
#引用
$value = "ATCG";
$valueRef = \$value;
#去引用
$deref = ${$valueRef};
print "$value\n$valueRef\n$deref\n";

#匿名引用
$valueRef = \"ATCG";
print "$valueRef\n${$valueRef}\n";
数组引用
#引用
@seq = qw(ATCG GCTA AAGG);
$arrayRef = \@seq;
#去引用
@deref = @{$arrayRef};
print "$arrayRef\n@deref\n";

#取出数组元素
print $arrayRef->[0], $arrayRef->[1], $arrayRef->[2]."\n";

#匿名引用
$seq = ["ATTTAC", "AACCGG","GGCCTT"]; #注意是[]不是()
print $seq->[0], $seq->[1], $seq->[2]."\n";

#多维数组
$seqs = [["ATTTAC", "AACCGG","GGCCTT"],["ATTTAC", "AACCGG","GGCCTT"],["ATTTAC", "AACCGG","GGCCTT"]];
print $seqs."\n";
print $seqs->[0], $seqs->[1], $seqs->[2]."\n";
print $seqs->[0][1], $seqs->[1]->[0], $seqs->[2]."\n";
哈希引用
#引用
use Data::Dumper;
my %hash = ("k1"=>"abc1","k2"=>"abc2","k3"=>"abc3");
my $refhash = \%hash;
#去引用
my %deref = %{$refhash};
print $refhash."\n";
print Dumper (\%deref)."\n";  #打印哈希

#取出键值对,两种方法
for my $k(keys %{$refhash}){
	print "key: $k\t$$refhash{$k}\n";
}
for my $k(keys %$refhash){
	#去引用时,{}可以省略
	print "key: $k\t$refhash->{$k}\n";
}

#匿名引用
my $refhash1 = {"k1"=>"abc1","k2"=>"abc2","k3"=>"abc3"}; #注意{}
print $refhash1."\n";

  • 15
    点赞
  • 98
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值