Perl语言基础(一)
简介
什么是Perl语言?
Perl一般被称为“实用报表提取语言”( Practical Extraction and Report Language)
Perl最初的设计者为拉里沃尔(Larry Wall)他于1987年12月18日发表。
“Perl”,有大写的P,是指语言本身;"perl”,小写的p,是指程序运行的解释器。
Perl语言特点
为什么Perl语言适合处理生物数据
基础语法
Perl 程序有声明与语句组成,程序自上而下执行,包含了循环,条件控制,每个语句以分号 (;) 结束。
Perl 语言没有严格的格式规范,你可以根据自己喜欢的风格来缩进。
单引号和双引号
1 | #!/usr/bin/perl |
输出结果如下:
Hello, world Hello, world\n
从结果中我们可以看出,双引号 \n 输出了换行,而单引号没有。
Perl双引号和单引号的区别:
(1)双中有双,单中有单都需要 \ 转义。
(2)双中有单或单中有双均不需要转义。
(3)单引号直接了当,引号内是什么就显示什么,双引号则需要考虑转义或变量替换等。双引号可以正常解析一些转义字符与变量,而单引号无法解析会原样输出。
Perl 数据类型
Perl语言中数组主要有 标量 数组 哈希
-
标量
标量是 Perl 语言中最简单的一种数据类型。这种数据类型的变量可以是数字,字符串,浮点数,不作严格的区分。在使用时在变量的名字前面加上一个$
,表示是标量。
例如:
$myfirst=123; #数字123 $mysecond="123"; #字符串123
-
数组
数组变量以字符 @ 开头,索引从 0 开始,如:@arr=(1,2,3)
-
哈希
哈希是一个无序的 key/value 对集合。可以使用键作为下标获取值。哈希变量以字符 % 开头。
eg%h=('a'=>1,'b'=>2);
转义字符
转义字符 | 含义 |
---|---|
\\ |
反斜线 |
\' |
单引号 |
\" |
双引号 |
\a | 系统响铃 |
\b | 退格 |
\f | 换页符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\0nn | 创建八进制格式的数字 |
\xnn | 创建十六进制格式的数字 |
\cX | 控制字符,x可以是任何字符 |
\u | 强制下一个字符为大写 |
\l | 强制下一个字符为小写 |
\U | 强制将所有字符转换为大写 |
\L | 强制将所有的字符转换为小写 |
\Q | 将到\E为止的非单词(non-word)字符加上反斜线 |
\E | 结束\L、\U、\Q |
标量
标量是一个简单的数据单元。
标量可以是一个整数,浮点数,字符,字符串,段落或者一个完整的网页。
以下实例演示了标量的简单应用:
1 | #!/usr/bin/perl |
执行以上程序,输出结果为:
Age = 20 Name = Runoob Salary = 130.5
1、Perl中最基本的数据类型
2、可以是数字、字母
3、无需定义类型
4、“单数”为标量
直接量
在程序中直接定义一个值,就叫做直接量。
1e-5
-40
“Hello,world”
print"2.4+3"
1 000 100
数字操作符
加2+3
减5.1-2.4
乘3*12
除14/2(除数不能为0)
取模10%3
乘幂 2**3
字符串运算
1、所谓字符串就是一连串的字符组合,字符可以是字母,也可以是数字,包括标点等;
2、对DNA序列处理本质上就是处理字符串;3、字符串可以为空
4、需要“引号”
”序列”字符串处理
序列也是字符串
ATGAATCCAAATCAGAAGATAACAGCAATTGGCTCTGTTTCTCTAATCATTGCGATAATATGTCTCCTCATGCAAATTGCCATCTTAACAACGACTATGACATTACAATTCTGGCAGAAAGAATGCAGTAACCCATCGAATAATCAAGTGATGCCATGTGAACCGATCATAATAGAA
计算长度反向
碱基互补配对替换
截取
翻译成氨基酸
单引号与双引号字符串的差别
-
单引号内的内容表示内容本身(单引号和反斜线除外);
-
单引号内表示单引号和反斜线需要转意;
Print ‘she said that:’ hello,world’ -
双引号支持反斜线转意;
例:print’hello , world!\n’
print"hello , world !\n"
字符串操作符
字符串连接
使用.
: "hello ". “world”
使用x
: “fred” x 3
5x4=20?或者5555?
54
“Z”. 57
标量变量
标量变量用美元$表示
变量的命名规范
1、不能以数字开头$100
2、可以以字母下划线开头,后面可以有数字
3、严格区分大小写
4、命名最好与变量用途相关,不要过短
5、不要采用内部保留变量名 (eg ENV…)
变量赋值
1 | $dna="ATTTTTTGC"; |
(注意:这里的=
不代表数学意义上的等于,而是赋值的意思;==
才代表数学意义上的等于)
操作符(运算符)优先级
2+3*4结果等于14,
gene_num+4;
(2+3)*4结果等于20,
运算符符 | 结合性 | 描述 |
---|---|---|
++, – | 无 | 自增,自减 |
-, ~, ! | 从右到左 | 单目 |
** | 从右到左 | 乘方 |
=~, !~ | 从左到右 | 模式匹配 |
*, /, %, x | 从左到右 | 乘,除,取余,重复 |
+, -, . | 从左到右 | 加,减,联接 |
<<, >> | 从左到右 | 移位 |
-e, -r, | 无 | 文件状态 |
<, <=, >, >=, lt, le, gt, ge | 从左到右 | 不等比较 |
==, !=, <=>, eq, ne, cmp | 从左到右 | 相等比较 |
& | 从左到右 | 位与 |
, ^ | 从左到右 | 位或,位异或 |
&& | 从左到右 | 逻辑与 |
从左到右 | ||
… | 从左到右 | 列表范围 |
? and : | 从右到左 | 条件操作符 |
=, +=, -=, *=, | 从右到左 | 赋值 |
其他 | ||
, | 从左到右 | 逗号操作符 |
not | 从左到右 | Low-precedence logical NOT |
and | 从左到右 | lLow-precedence logical AND |
or, xor | 从左到右 | lLow-precedence logical OR and XOR |
比较运算符
表格实例中设置变量 $a 为 10, $b 为 20。
运算符 | 描述 | 实例 |
---|---|---|
== |
检查两个操作数的值是否相等,如果相等则条件为 true,否则为 false。 | ($a == $b) 为 false |
!= |
检查两个操作数的值是否相等,如果不相等则条件为 true,否则为 false。 | ($a != $b) 为 true。 |
<=> |
检查两个操作数的值是否相等, 如果左边的数小于右边的数返回 -1,如果相等返回 0, 如果左边的数大于右边的数返回 1 。 | ($a <=> $b) 返回 -1。 |
> |
检查左操作数的值是否大于右操作数的值,如果是则条件为 true,否则为 false。 | ($a > $b) 返回 false。 |
< |
检查左操作数的值是否小于右操作数的值,如果是则条件为 true,否则返回 false。 | ($a < $b) 返回 true。 |
>= |
检查左操作数的值是否大于或等于右操作数的值,如果是则条件为 true,否则返回 false。 | ($a >= $b) 返回 false。 |
<= |
检查左操作数的值是否小于或等于右操作数的值,如果是则条件为 true,否则返回 false。。 | ($a <= $b) 返回 true. |
换行符
回车和换行
在linux系统下是换行\n;
在mac系统下是回车\r;
windows系统下回车加换行两个字符\r\n;
不同系统之间换行符的转换
dos2unixwindows转换为linux
unix2dos:linux转换为windows
unix2mac :linux转换为mac
mac2unix:mac转换为linux
chomp函数
功能:去除换行符
test= "hello,world\n'
chomp (test);# “hello,world”
chomp (test);# "hello,world"
chomp (test);# “hello,world”
chomp ($test);# “hello,world”
chop函数
功能:每输入一次就会去掉后面一个字符
1 | $test= "hello,world\n |
列表和数组
列表(list)指的是标量的有序集合
数组(array)则是存储列表的变量。
@array=[1,2,3,4,5];
@array=[1, “hello”,undef, $dna,5];
数组的访问
@array=[1,2,3,4,5];
array[1]=2;
array[3]=4;
array[99]=100;
数组的元素个数
@array=[1,2,3,4,5];
数组最后一个元素角标#array;
数组元素个数=#array+1;
构建列表
-
括号,元素之间用逗号隔开;
(1,2,3,4,5) -
范围操作符(…)每次加一
@number=(1..100); print "@number\n";
-
qw操作符,可以省略逗号
@strings=qw (fred barney betty wilma dino); @stringl=qw !fred barney betty wilma dino!; @string2= #fred barney betty wilma dino#; @string3=qw /fred barney betty wilma dino/; @string4=qw {fred barney betty wilma dino}; dstring5=qw <fred barney betty wilma dino>;
数组赋值
eg
1 | (Sfred, Sbarney, Sdino)=("flintstone","rubble", undef); |
output:
flintstone
rubble
split和join
split将字符串根据固定的分隔符进行切割,切割后得到一个数组;
1 | #!/usr/bin/perl |
join与split刚好相反,它的作用是将数组连接成一个标量
1 | $new_scalar=join ":",@array; |
Perl帮助文档
通过访问perl官方文档
在linux系统下 输入 perldoc
即可
1 | perldoc -f chomp #查找函数的功能 |
语法手册
手册页 | 内容 |
---|---|
perl | 有些什么 perl 手册页 |
perldata | 数据类型 |
perlsyn | 语法 |
perlop | 操作符和优先级 |
perlre | 正则表达式 |
perlvar | 预定义变量 |
perlsub | 子过程 |
prelfunc | 内建函数 |
perlmod | 如何令 Perl 模块工作 |
perlref | 参考手册 |
perlobj | 对象 |
perlipc | 进程间通讯 |
perlrun | 如何运行 Perl 命令,以及命令行开关 |
perldebug | 调试 |
perldiag | 诊断信息 |
faq手册
手册页 | 内容 |
---|---|
perlfaq1 | 关于 Perl 的通用信息 |
perlfaq2 | 获取和学习 Perl |
perlfaq3 | 编程工具 |
perlfaq4 | 数据操作 |
perlfaq5 | 文件和格式 |
perlfaq6 | 正则表达式 |
perlfaq7 | 通用 Perl 语言信息 |
perlfaq8 | 系统交互 |
perlfaq9 | 网络 |
移植相关手册
手册页 | 内容 |
---|---|
perlamiga | Amiga 移植 |
perlcygwin | Cygwin 移植 |
perldos | MS-DOS 移植 |
perlhpux | HP-UX 移植 |
perlmachten | Power MachTen? 移植 |
perlos2 | OS/2 移植 |
perlos390 | OS/390 移植 |
perlvms | DEC VMS 移植 |
perlwin32 | MS-Windows 移植 |
在平时编程中要熟练查看帮助文档
输入与输出
open函数文件读写
1 | #!/usr/bin/perl -w |
文件句柄
在文件I/O中,要从一个文件读取数据,应用程序首先要调用操作系统函数并传送文件名,并选一个到该文件的路径来打开文件。该函数取回一个顺序号,即Perl文件句柄(filehandle)
文件句柄用来对应要操作的文件系统中的文件,这么说不太严谨,但比较容易理解。首先为要打开的文件绑定文件句柄(称为打开文件句柄),然后在后续的操作中都通过文件句柄来操作对应的文件,最后关闭文件句柄。
perl保留文件句柄
STDIN, STDOUT, STDERR,DATA,ARGV和ARGVOUT
标准输入,标准输出,错误输出
@ARGV
perl cds2pep.pl gene.ffn protein.faa 1
cds2pep.pl $O
gene.ffn: $ARGV[0] 命令行第1个参数
protein.faa: $ARGV[1]命令行第二个参数
1: $ARGV[2]命令行第三个参数
1 | !/usr/bin/perl -w |
示例
1 | #!/usr/bin/perl -w |
格式转换程序
fastq转fasta
首先两个文件差别在于 fasta文件为四行,fastq为两行
fasta为>开头,fastq为@开头
1 | #fastq格式文件 |
1 | #!/usr/bin/perl -w |
=~将左边的值交给右边做匹配,并直接修改左边的值;相当于shell的-i 's////g'
哈希
哈希是 key/value 对的集合。
Perl中哈希变量以百分号 (%) 标记开始。
访问哈希元素
访问哈希元素格式:${key}。
以下是一个简单的哈希实例:
1 | #!/usr/bin/perl |
创建哈希
创建哈希可以通过以下两种方式:
- 为每个 key 设置 value
1 | $data{'google'} = 'google.com'; |
- 通过列表设置
列表中第一个元素为 key,第二个为 value。
1 | %data = ('google', 'google.com', 'runoob', 'runoob.com', 'taobao', 'taobao.com'); |
读取哈希值
哈希值提取到数组语法格式:@{key1,key2}。
1 | #!/uer/bin/perl |
执行以上程序,输出结果为:Array : 45 40
读取哈希的 key 和 value
读取所有key
可以使用 keys 函数读取哈希所有的键,语法格式如下:keys %HASH
eg
1 | #!/usr/bin/perl |
输出结果为:
1 |
|
类似的可以使用 values 函数来读取哈希所有的值,语法格式如下:values %HASH
该函数返回所有哈希的所有 value 的数组。
1 | #!/usr/bin/perl |
输出结果为:
1 | google.com |
检测元素是否存在
在哈希中读取不存在的 key/value 对 ,会返回 undefined 值,且在执行时会有警告提醒。
为了避免这种情况,可以使用 exists 函数来判断key是否存在,存在的时候读取:
1 | #!/usr/bin/perl |
获取哈希大小
1 | #!/usr/bin/perl |
输出结果为:
1 - 哈希大小: 3 2 - 哈希大小: 3
哈希中添加或删除元素
添加 key/value 对可以通过简单的赋值来完成。但是删除哈希元素你需要使用 delete 函数:
1 | #!/usr/bin/perl |
输出结果为:
1 - 哈希大小: 3 2 - 哈希大小: 4 3 - 哈希大小: 3
迭代哈希
可以使用 foreach 和 while 来迭代哈希:
使用 foreach
1 | #!/usr/bin/perl |
使用 while
1 | #!/usr/bin/perl |
执行以上程序,输出结果为:
1 | google.com |
示例测试
数据
Heilongjiang Haerbin
Jilin Changchun
Liaoning Shenyang
Hebei Shijiazhuang
Beijing Beijing
Tianjin Tianjin
Shanxi Taiyuan
Shandong Jinan
Anhui Hefei
Jiangsu Nanjing
1 | #!/uer/bin/perl -w |
序列提取
哈希,在生物数据分析中最常用的一个方式,序列提取。根据固定的ID从另一个文件或者数据库中将数据提取出来,也就是根据一个小数据从一个大数据中提取数据。
处理方式:将小的数据集存储到一个哈希中,然后在遍历大的数据集查看哈希是否存在,如果 存在即输出,不存在不输出任何东西,循环继续进行
1 | #!/usr/bin/perl -w |
子程序
Perl 子程序也就是用户定义的函数。
Perl 子程序即执行一个特殊任务的一段分离的代码,它可以使减少重复代码且使程序易读。
Perl 子程序可以出现在程序的任何地方,语法格式如下:
示例
1 | sub subroutine{ |
执行以上程序,输出结果为:
Hello, world!
向子程序传递参数
Perl 子程序可以和其他编程一样接受多个参数,子程序参数使用特殊数组 @_ 标明。
因此子程序第一个参数为 $[0], 第二个参数为 $[1], 以此类推。
不论参数是标量型还是数组型的,用户把参数传给子程序时,perl默认按引用的方式调用它们。
定义求和函数
1 | #!/usr/bin/perl -w |
定义求平均值函数
1 | #!/usr/bin/perl |
执行以上程序,输出结果为:
传入的参数为 : 10 20 30 第一个参数值为 : 10 传入参数的平均值为 : 20
向子程序传递列表
由于 @_ 变量是一个数组,所以它可以向子程序中传递列表。
但如果我们需要传入标量和数组参数时,需要把列表放在最后一个参数上,如下所示:
1 | #!/usr/bin/perl |
以上程序将标量和数组合并了,输出结果为:
列表为 : 10 1 2 3 4
Perl 正则表达式
Perl的正则表达式的三种形式,分别是匹配,替换和转化:
匹配:m//(还可以简写为//,略去m)
替换:s///
转化:tr///
这三种形式一般都和 =~ 或 !~ 搭配使用, =~ 表示相匹配,!~ 表示不匹配。
匹配操作符
匹配操作符 m// 用于匹配一个字符串语句或者一个正则表达式,例如,要匹配 标量 $bar 中的 “run”,代码如下所示:
1 | #!/usr/bin/perl -w |
模式匹配修饰符
模式匹配有一些常用的修饰符,如下表所示:
修饰符 | 描述 |
---|---|
i | 忽略模式中的大小写 |
m | 多行模式 |
o | 仅赋值一次 |
s | 单行模式,“.“匹配”\n”(默认不匹配) |
x | 忽略模式中的空白 |
g | 全局匹配 |
cg | 全局匹配失败后,允许再次查找匹配串 |
示例 - 提取以ATG开头-TAA结尾的序列
1 | #!/usr/bin/perl -w |
单词锚定
search、searches ,searcher,searched,
searching、researching
-
只匹配search
/\bsearch**\b**/ -
匹配search、searches、 searcher、searched、searching
/\bsearch/ -
只匹配search、 research
/search**\b**/ -
不匹配search
/\Bsearch**\B**/
正则表达式变量
perl处理完后会给匹配到的值存在三个特殊变量名:
1 | $`: 匹配部分的前一部分字符串 |
示例
1 | #!/usr/bin/perl |
执行以上程序输出结果为:
匹配前的字符串: welcome to
匹配的字符串: lxz
匹配后的字符串: 9.com
替换操作符
基本格式:s/PATTERN/REPLACEMENT/;
1 | #!/usr/bin/perl |
执行以上程序输出结果为:
welcome to lxz site.
替换操作修饰符
替换操作修饰符如下表所示:
修饰符 | 描述 |
---|---|
i | 如果在修饰符中加上"i",则正则将会取消大小写敏感性,即"a"和"A" 是一样的。 |
m | 默认的正则开始"^“和结束”"。 |
o | 表达式只执行一次。 |
s | 如果在修饰符中加入"s",那么默认的"."代表除了换行符以外的任何字符将会变成任意字符,也就是包括换行符! |
x | 如果加上该修饰符,表达式中的空白字符将会被忽略,除非它已经被转义。 |
g | 替换所有匹配的字符串。 |
e | 替换字符串作为表达式 |
转化操作符
以下是转化操作符相关的修饰符:
修饰符 | 描述 |
---|---|
c | 转化所有未指定字符 |
d | 删除所有指定字符 |
s | 把多个相同的输出字符缩成一个 |
以下实例将变量 $string 中的所有小写字母转化为大写字母:
1 | #!/usr/bin/perl |
执行以上程序输出结果为:
WELCOME TO LXZ SITE.
以下实例使用 /s 将变量 $string 重复的字符删除:
实例
1 | #!/usr/bin/perl |
执行以上程序输出结果为:
lxz
更多实例:
string =~ tr/\d/ /c; # 把所有非数字字符替换为空格
string =~ tr/\t //d; # 删除tab和空格
$string =~ tr/0-9/ /cs # 把数字间的其它字符替换为一个空格。
更多正则表达式规则
表达式 | 描述 |
---|---|
. | 匹配除换行符以外的所有字符 |
x? | 匹配 0 次或一次 x 字符串 |
x* | 匹配 0 次或多次 x 字符串,但匹配可能的最少次数 |
x+ | 匹配 1 次或多次 x 字符串,但匹配可能的最少次数 |
.* | 匹配 0 次或多次的任何字符 |
.+ | 匹配 1 次或多次的任何字符 |
{m} | 匹配刚好是 m 个 的指定字符串 |
{m,n} | 匹配在 m个 以上 n个 以下 的指定字符串 |
{m,} | 匹配 m个 以上 的指定字符串 |
[] | 匹配符合 [] 内的字符 |
[^] | 匹配不符合 [] 内的字符 |
[0-9] | 匹配所有数字字符 |
[a-z] | 匹配所有小写字母字符 |
[^0-9] | 匹配所有非数字字符 |
[^a-z] | 匹配所有非小写字母字符 |
^ | 匹配字符开头的字符 |
$ | 匹配字符结尾的字符 |
\d | 匹配一个数字的字符,和 [0-9] 语法一样 |
\d+ | 匹配多个数字字符串,和 [0-9]+ 语法一样 |
\D | 非数字,其他同 \d |
\D+ | 非数字,其他同 \d+ |
\w | 英文字母或数字的字符串,和 [a-zA-Z0-9_] 语法一样 |
\w+ | 和 [a-zA-Z0-9_]+ 语法一样 |
\W | 非英文字母或数字的字符串,和 [^a-zA-Z0-9_] 语法一样 |
\W+ | 和 [^a-zA-Z0-9_]+ 语法一样 |
\s | 空格,和 [\n\t\r\f] 语法一样 |
\s+ | 和 [\n\t\r\f]+ 一样 |
\S | 非空格,和 [^\n\t\r\f] 语法一样 |
\S+ | 和 [^\n\t\r\f]+ 语法一样 |
\b | 匹配以英文字母,数字为边界的字符串 |
\B | 匹配不以英文字母,数值为边界的字符串 |
a | b |
abc | 匹配含有 abc 的字符串 (pattern) () 这个符号会记住所找寻到的字符串,是一个很实用的语法.第一个 () 内所找到的字符串变成 $1 这个变量或是 \1 变量,第二个 () 内所找到的字符串变成 $2 这个变量或是 \2 变量,以此类推下去. |
/pattern/i | i 这个参数表示忽略英文大小写,也就是在匹配字符串的时候,不考虑英文的大小写问题. \ 如果要在 pattern 模式中找寻一个特殊字符,如 “*”,则要在这个字符前加上 \ 符号,这样才会让特殊字符失效 |