文章目录
8.3 Perl 语言基础入门
- 详见视频:Perl 语言基础入门-01 P137
● Perl:Practical Extraction and Report Language 官网免费下载 (网不好可能打不开),支持多操作系统
- 直译语言:Interpreted Language
- 序列处理:特别适合字符串(序列)处理
- 文件处理:方便简洁的文件写入与写出
- 模式匹配:全面支持正则表达式
8.3.1 第一个 Perl
- 创建一个文本文件,命名为 test.pl
- 第一行写 Perl 执行环境(安装路径)
linux 写:#!/usr/bin/perl
Windows 写:#!C:/Strawberry/perl/bin/perl.exe
- 第二行写一个简单的语句,比如:
print "He1lo world!";
- 保存 test.pl,打开 cmd 命令窗口。
- 切换到 test.pl 所在目录。
cd Desktop
- 执行
perl test.pl
命令,运行你的第一个程序。
8.3.2 Perl 的基本规则
- 每条语句后面必须有"
;
"。 - 注释前面加"
#
",只对单行有效。 - 变量的定义极其简单随便:
◆ 不用提前声明变量,随用随定义;
◆ 不用定义变量类型,赋值后程序会自动判断;
◆ 变量名区分大小写,以字母开头,不能有特殊字符;
◆ 变量名前面加"$
“,用”=
"赋值。$scalar = expression
● 各种引号的使用:
- 单引号
''
完全直白的翻译引号里的全部内容。
- 双引号
""
可以识别引号里的变量和反义字符。
- 反引号
``
将引号里的内容当成命令来执行。
● 各种操作符的使用:
-
比较操作符 Comparison Operators:
针对字符串的比较操作符和针对数字的比较操作符是不一样的!
◆ 数字比字母小!
◆ 大写字母比小写字母小!
◆ 由小到大:数字 [0-9]、大写字母 [A-Z]、小写字母 [a-z]
-
逻辑操作符 Logical Operators:
可以直接写:or
,and
,not
也可以用符号代替:||
,&&
,!
特殊逻辑操作符:xor
异或
△a xor b = (a' and b) or (a and b')
(a’ = not a)
如果 a、b 两个值不相同,则异或结果为1
。如果 a、b 两个值相同,异或结果为0
。 -
字符串操作符 String Operators:
.
字符串拼接相连
x
字符串重复复制
.=
字符串拼接相连后赋值$string1 = "potato"; $string2 = "head"; $string3 = $string1 . $string2; #patatohead $string4 = $string1 x 2; #patato $string1 .= $string2; #string1 = patatohead
8.3.3 字符串常用函数
-
Perl 有许多提前定义好的函数:
函数名 ( 参数 1, 参数 2,... 参数 n)
注意:
参数间的逗号是必不可少的
括起参数的括号则是可有可无的 -
length
函数:
语法:length($string);
说明:求出字符串$string 的字节值(长度)。$string="Per15"; $size=length($string); #这时 $size=5 #计算一条氨基酸序列的长度 $seq="GHMGSSVLEELVQLVKDKNIDISIKYDPRKDSEVEANRVITDDIELLKKILAYFLPEDAILKGGHYDNQLQNGIKRVKEFLESSPNTQWELRAFMAVMHFSLTADRIDDDILKVIVDSMNHHGDARSKLREELAELTAE"; $len=length($seq); print "The protein contains $len amino acids.";
-
substr
函数:
语法:substr($string, offset, 1ength);
说明:截取字符串$string 的子字符串。
★ 注意:第一位是 0,不是 1。
offset
代表起始字符的位置,而 offset 如果是负值的话,就会从字符串右边开始指定字符。
length
代表引用的字符串长度,如果省略 length 则代表从起始值到字符串的最后一个字符长度。
$s1=substr("perl5",2,2); #$s="rl" 从第二个字符串后开始截取 2 个字符串 $s2=substr("perl5",1); #$s="erl5" 从第一个字符串后开始截取剩余字符串 $s3=substr("perl5",-5,3); #$s="per" 从倒数第五个字符串开始截取 3 个字符串 #提取出蛋白质序列的功能区,功能区位于第 12 个氨基酸到第 23 个氨基酸。 $seq="GHMGSSVLEELVQLVKDKNIDISIKYDPRKDSEVEANRVITDDIELLKKILAYFLPEDALKGGHYDNQLQNGIKRVKEFLESSPNTQWELRAFMAVMHFSLTADRIDDDILKVIVDSMNHHGDARSKLREELAELTAE"; $begin=11; $end=22; $length=$end-$begin+1; $region=substr($seq, $begin, $length); print "The functional region is $region.";
-
index
函数:
语法:index($string, $substring, position)
说明:返回所要找寻的字符$substring
在字符串$string
中的位置(只返回找到的第一个位置),如果找不到,则返回-1
。$substring
是要寻找的字符;
position
代表从哪一个位置开始寻找,假如省略就是从头开始找起。$s1=index("pell5","p"); #$s1=0 $s2=index("pell5","l",2); #$s2=2 只返回找到的第一个位置 $s3=index("pell5", "perl"); #$s3=-1 #查找某功能区在一条蛋白质序列里的位置。 $seq="GHMGSSVLEELVQLVKDKNIDISIKYDPRKDSEVEANRVITDDELLKKILAYFLPEDAILKGGHYDNQLQNGIKRVKEFLESSPNTQWELRAFMAVMHFSLTADRIDDDILKVIVDSMNHHGDARSKLREELAELTAE"; $region="KEFLESSPNT"; $begin=index($seq, $region)+1; #起始位置,注意获取 index 后加一 $end=$begin+length($region)-1; #结束位置,注意减一 $begin_aa=substr($region,0,1); #第一个氨基酸 $end_aa=substr($region,-1,1); #最后一个氨基酸 print "The functional region is from $begin_aa$begin to $end_aa$end.";
8.3.4 数组常用函数
-
数组 Array 是包含在括号
()
里的一组元素。
-元素可为任何值也可为空,以逗号相隔
-随时可以增减元素的个数
-数组用@
符号表示,比如:@arr("A","T","C","G")
-数组中的一个元素等于一个变量,写成:$arr[index_number]
print $arr[0]; #A print $arr[1,3]; #TG print @arr; #ATCG
-
scalar
函数:元素个数
语法:scalar(@array)
说明:返回数组@array
的元素个数。@arr=("A","B","C"); #定义一个数组 $num=scalar(@arr); #这时$num=3 #批量处理一组 Uniprot ID 前,先数数这一组 ID 的个数。 @ids=("Q6GV17", "Q9BXR5", "B3Y669", "COLSK8"); $count=scalar(@ids); print "$count ids : @ids";
-
reverse
函数:逆序
语法:reverse(@array)
说明:将数组@array
中的元素由后到前逆向排列。 -
sort
函数:升序
语法:sort[{$a<=>$b}](@array)
说明:将数组@array
中的元素按 ASCII 码顺序由小到大排序。加上{$a<=>$b}
之后按数字大小排序。@arr1=(21,1,2,12); @arr2=reverse(@arr1); #@arr2=(12,2,1,21); 元素逆序 @arr3=sort(@arr); #@arr2=(1,12,2,21) 按字符串大小排序 @arr4=sort{ $a<=>$b}(@arr); #@arr3=(1,2,12,21) 按数字大小排序 #将一组计算结果数值升序/降序排列。 @value=(10,34,24,16,4,7); @value1=sort{ $a<=>$b}(@value); # 升序 @value2=reverse(@value1); # 降序 print "ascending order : @value1\n"; #\n 代表换行 print "descending order : @value2";
-
pop
函数:删除最后一个
语法:pop(@array)
说明:将数组@array
的最后一个元素删除,并将删除的元素返回。@arr=("A","B","C"); $rm=pop(@arr); #@arr=("A", "B"), $rm="C"
-
push
函数:最后添加
语法:push(@array,$newelement/@newarray)
说明:在数组@array
的最后加上新元素或者新数组。@arr=("A","B","C") ; push(@arr,"D") ; #@arr=("A", "B","C","D") #由大到小排序,同时去掉最小值,并在最后添加元素的个数。 @value=(10,34,24,16,4,7); @value1=sort{ $a<=>$b}(@value); @value=reverse(@value); pop(@value); push(@value, scalar(@value)); print "new value : @value";
-
shift
函数:删除第一个
语法:shift(@array)
说明:与 pop 相似,将数组@array
的第一个元素删除,并将删除的元素返回。@arr=("A","B","C"); $rm=shift(@arr); #@arr=("B", "C"), $rm="A"
-
unshift
函数:前面添加
语法:unshift(@array,$newelement/@newarray)
说明:与 push 相似,在数组@array
的最前面加上新元素或者新数组。@arr=("A","B"); unshift(@arr,"X") ; #@arr=("X", "A","B") #由大到小排序,同时去掉最大值,并在最前面添加元素的个数。 @value=(10,34,24,16,4,7); @value1=sort{ $a<=>$b}(@value); @value=reverse(@value); shift(@value); unshift(@value, scalar(@value)); print "new value : @value";
-
join
函数:连接:
语法:join($string, @array)
说明:用指定字符$string
将数组@array
中的元素连接成字符串,并将该字符串作为结果返回。@arr=("A" , "B" , "C") ; $get=join(":", @arr); #$get="A:B:C"
-
split
函数:分割:
语法:split(/pattern/, $string)
说明:把字符串$string
按照pattern
(分隔符) 进行分割,并把分割后的结果放入数组中。$seq="15:32:54"; @arr=split(/:/, $seq) ; #@arr=("15","32","54") # 获取 FASTA 格式序列的纯序列部分。 $fasta=">sp|P33316|DUT_HUMAN MTPLCPRPALCYHFLTSLLRSAMQNARGARQRA EAAVLSGPGPPLGRAAQHGIPRPLSSAGRLSQG CRGASTVGAAGWKGELPKAGGSPAPGPETP"; @line=split(/\n/, $fasta); # 按换行符分割成行数 n 个字符串并放入数组 line shift(@line); # 去掉数组中的第 1 个字符串,即">"开头的第一行 $seq=join("", @line); #拼接其他字符串,即纯序列 print $seq;
8.4 Perl 语言基础高级
8.4.1 if 条件语句
● 语法一:
- if 条件语句的“条件”放在括号
()
里
括号里的“条件”是逻辑表达式
如果逻辑表达式判断为true
: 执行if
后面大括号{}
里的语句
如果逻辑表达式判断为false
: 执行else
后面大括号{}
里的语句
注意:if 和 else 可以不成对出现,即,可以只有 if 没有 else, 而不能只有 else 没有 if !$a=10; $b=15; if ($a > $b) { print "a is bigger!"; } else { print "b is bigger!"; }
● 语法二:
- 如果逻辑表达式 1 判断为
true
: 执行 statement1 - 如果逻辑表达式 1 判断为
false
:
继续判断elsif
后面的逻辑表达式 2
如果逻辑表达式 2 判断为 true: 执行 statement2
如果逻辑表达式 2 判断为 false: 执行 statement3if ($a == 5) { print '$a is 5'; } elsif ($a == 10) { print '$a is 10'; } elsif ($a == 15) { print '$a is 15'; } else { print '$a is not (5 or 10 or 15)'; }
8.4.2 for 循环语句
● 语法一:for
- init 会首先被执行,且只会被执行一次。这一步是声明并初始化循环控制变量。比如:
$i=1
; - 接下来,会判断 condition。 如果为 true, 则执行循环主体。如果为 false, 则不执行。比如:
$i<10;
- 在执行完循环主体后,控制流会跳回 increment 语句,并更新循环控制变量。比如:
$i++
- 再次判断 condition,重复以上过程,直到条件变为 false 时,循环终止。
# 九九乘法表 for ($i=1; $i<10; $i++) { for($j=1; $j<10; $j++) { $x=$i*$j; print "$i x $j = $x\t"; } print "\n"; }
● 语法二:foreach
foreach (@array) {
statement1;
……
}
-
针对数组
@array
中的每一个元素,执行循环主体。(遍历数组) -
用变量
$_
代表本轮循环中所抓取的当前元素。 -
数组中每一个元素依次轮一遍之后,循环结束。
# 奇数偶数? @a=(1, 12, 33, 25, 98, 34, 55, 76, 18, 10); foreach (@a) { if ($_ % 2 == 0) # % 取余数 { print "$_ is even. \n"; } else { print "$_ is odd. \n"; } }
8.4.3 文件读入与写出
-
读入文件:
open(FH, "read.txt");
打开当前路径中的 read.txt 文件。FH 为一个文件读写事件的标识,可自行定义名字。
@get = <FH>;
将读取的文件内容存入数组@get
中,根据换行"\n"分割元素,即,一行一个元素。
close FH;
读取结束,关闭文件标识 FH。open(FH, "read.txt"); @get = <FH>; close FH;
-
写出文件:
open(FH, ">write.txt");
打开/创建当前路径中的 write.txt 文件,并往其中写出内容。“>
” 代表写出,且文件中原有内容将被覆盖。
print FH "Hello world!\n";
“print FH” 代表将双引号中的内容写出到文件标识 FH 所代表的文件,而非写出到屏幕。
close FH;
写出结束,关闭文件标识 FH。open(FH, ">write.txt"); print FH "Hello world!\n"; close FH;
-
续写文件:
open(FH, ">>write.txt");
打开/创建当前路径中的 write.txt 文件,并往其中写出内容。“>>
” 代表续写,文件中原有内容不会被覆盖。
print FH "Hello world!\n";
同写出文件。
close FH;
写出结束,关闭文件标识 FH。open(FH, ">>write.txt"); print FH "Hello world!\n"; close FH;
-
屏幕输入:
print "What's your name?\n";
屏幕打印一句话
$name = <STDIN>;
STDIN 说明$name
应通过屏幕输入赋值。光标将停留以等待用户输入内容,输入后回车。
chomp($name);
chomp 函数用于去掉屏幕输入内容最后的回车。
print "Hello $name!";
打印获取的屏幕输入值。print "What's your name?\n"; $name = <STDIN>; chomp($name); print "Hello $name!";
8.4.4 获取下载网页
- 基本语句:
# 引用 LWP 模块,以使用 get 函数
use LWP::Simple;
# 将一个 FASTA 序列的网址赋值给变量 $url
$url='http://www.uniprot.org/uniprot/Q6GV17.fasta';
# get 函数获取$url 网址打开页面的全部内容(获取页面源代码)
$content = get $url;
# 如果网址无法打开,die 函数将强制结束程序,并屏幕打印告知。
die "Couldn't get $url" unless defined $content;
# 将获取的网页内容打印出来。
print $countent;
8.4.5 应用实例:批量下载保存序列
- 批量下载并保存序列
use LWP::Simple;
open (FH, ">seq.fasta");
@ids= ("Q6GV17" , "Q9BXR5" , "B3Y669" , "COLSK8");
foreach (@ids) {
$url= "http://www.uniprot.org/uniprot/$_.fasta";
$content = get $url;
die "Couldn't get $url" unless defined $content;
print FH "$countent";
}
close FH;