Learning Perl mindmap

markmap website

# Perl markmap document

## STDIN/OUT

### STDOUT

- print:不会自动换行
- printf:格式化打印
- say:需要perl版本支持,会自动换行,类似于print函数

### STDIN

- chomp($var_name = \<STDIN>)
- chomp(@array = \<STDIN>)
- if file name have special character: use <<>> [double diamond reference](https://www.effectiveperlprogramming.com/2015/05/use-perl-5-22s-operator-for-safe-command-line-handling/)

## Build-in warnings

- use warnings;
- perl -w perl_program.pl
- #!/usr/bin/perl -w

## 引号

- 单引号:单引号内除了单引号和反斜线可以被转义,其他字符都是字面意思

- 双引号:双引号内可以内插变量,通过转义字符转义,表达式内插

- [q qq qw qr qx difference URL](https://programmerall.com/article/64241961690/)

- q():等价于单引号,括号可以使用其他符号替代

- qq():等价于双引号,括号可以使用其他符号替代

- qw():在每个字符串上加上单引号,括号可以使用其他符号替代

- qr():创建一个正则表达式,括号可以使用其他符号替代

- qx():等价于反引号,括号可以使用其他符号替代

- ```
	引用字符出现起止符需要转义
	say qq{abc\}def};  # 转义终止符
	say qq{abc\{def};  # 转义起始符
	say qq ad\aefa;    # 转义起始符a,输出daef
	```

- ```
	#双引号内可以变量内插,单引号内不能变量内插
	say "hello $name";    # hello junma
	say 'hello $name';    # hello $name
	say "hello\\world";  # hello\world
	say 'hello\\world';  # hello\world
	say "hello\"world, hello'world";  # hello"world, hello'world
	say 'hello\'world, hello"world';  # hello'world, hello"world
	```

## Heredoc

### 注意事项

- Heredoc end-mark不加引号,默认值为双引号
- Heredoc end-mark前后不能有空格,end-mark前后一致

### 变量可解析

- ```
	my $var = value;
	my $message = <<"MSG";
	This \$var is $var;
	MSG
	```

### 变量不可解析

- ```
	my $var = value;
	my $message = <<'MSG';
	This \$var is $var;
	MSG
	```

## 运算符号

### 数值运算符

- 1. \+ \- \* /:常规四则运算
	2. \*\*:幂指数运算
	3. %:模运算
	4. ++ --:自增/自减操作
	5. 数学运算过程会先尝试将结果转化为整数,如果有精度损失则保持浮点数格式

### 比较运算符

- ```
	数值     字符串      意义
	-----------------------------
	==       eq        相等
	!=       ne        不等
	<        lt        小于
	>        gt        大于
	<=       le        小于或等于
	>=       ge        大于或等于
	<=>      cmp       返回值-1/0/1
	```

### 逻辑运算符

- ```
	not expr          # 逻辑取反
	expr1 and expr2   # 逻辑与
	expr1  or expr2   # 逻辑或
	! expr            # 逻辑取反
	expr1 && expr2    # 逻辑与
	expr1 || expr2    # 逻辑或
	expr1 // expr2    # 逻辑定义或
	```

### 按位运算符

- ```
	&  按位与
	|  按位或
	^  按位异或
	~  按位取反
	<<  按位左移
	>>  按位右移
	```

## 标量

### 私有变量

- my:仅在当前作用域起作用
- local:在当前作用域及子作用域起作用
- state:变量在子程序调用过程中,保存之前的结果,仅适用于标量

### 数值标量

- $varname:单个数据的存储空间

- $varname = value

- ```
	数值表示:
	二进制:0b[0-1]
	八进制:0[0-7]
	十六进制:0x[0-f]
	数字之间可以使用下划线进行分隔,便于阅读
	$n = 1234;              # 十进制整数
	$n = 34_123_456;
	$n = 33_22_56;
	$n = 0b1110011;         # 二进制整数
	$n = 01234;             # 八进制整数
	$n = 0x1234;            # 十六进制整数
	$n = 12.34e-56;         # 指数定义方式
	$n = "-12.34e56";       # 字符串方式定义的数值
	$n = "1234";            # 字符串方式定义的数值
	$n = "   1234";         # 有前缀空白的字符串数值
	$n = "  123a";          # 可以当数值123使用,但warnings时会警告
	```

### 标量数值相关函数

- 1. int():截断为整数
	2. rand():生成[0,1)之间的随机数
	3. abs():返回数值的绝对值 [abs usage URL](https://www.geeksforgeeks.org/perl-abs-function/)
	4. hex():十六进制转换为十进制,参数一般为十六进制数值**字符串,数值本身会转换为十进制再处理**,变量需要进行处理
	5. oct():十六进制/八进制/二进制转换为十进制,参数一般为进制数值**字符串,数值本身会转换为十进制再处理**,变量需要进行处理

- ```
	hex() usage:
	1. hex('0xff'):对应数值255
	2. hex("0xff"):对应数值255
	3. hex(0xff):对应数值597,等价于hex('0x255')
	4. $num=0xff;hex($num);对应数值597
	5. $num='0xff';hex($num);对应数值255
	```

### 字符串标量

- \$varname = 'value' or \$varname = "value"

- ```
	字符转换操作
	\u 修改下一个字符为大写
	\l 修改下一个字符小写 
	\U 修改后面所有字符大写 
	\L 修改后面所有字符小写 
	\Q 使后面的所有字符都成为字面符号
	\E 结束\U \L或\Q的效果
	```

### 标量字符串相关函数

- 1. lc:后面的字符全部转换为小写
	2. uc:后面的字符全部转换为大写
	3. fc:unicode编码字符全部转换为小写
	4. lcfirst:第一个字符转换为小写
	5. ucfirst:第一个字符转换为大写
	6. chr():asicii码或unicode码转换为对应字符
	7. ord():字符转换为asicii码或unicode码
	8. chomp:去除行尾换行符
	9. chop:去除行尾字符
	10. index:获取字符在字符串中的索引位置
	11. substr:字符串提取子字符串

## 数组

### 数组声明和引用

- 数字数组声明:@array_name=(num1,num2,num3,...);
- 字符串数组声明:@array_name=('str1','str2','str3',...);
	字符串数组声明:@array_name=qw(str1 str2 str3 ...); 字符串存在空格不能使用这种方法
- 数组引用:$array_name[index],索引值可以为负数,反向索引
- **数组最后一个索引值**:${#array_name}
- **数组长度**:scalar @array_name

### 数组扩展

- @array_name=(@array_name,val1,val2,...);原数组基础上加新的数值
- @array_merge=(@array_name1,@array_name2,...);多个数组拼接成新的数组
- @array_name=(val1,val2,val3,...)[num1,num2,num3,...];列表切片,指定数值赋值给数组;

### 遍历数组方法

- ```
	#for usage
	for my $val (@arr) {
	    say "$val";
	}
	```

- ```
	#foreach usage
	forach my $val (@arr) {
	    say "$val";
	}
	```

- ```
	#控制变量在遍历数组后其数值不变
	my @arr = (11, 22, 33, 44);
	my $v = 3333;
	say \$v;
	say '---- before ----';
	for my $v (@arr) { say \$v; }
	say '---- after ----';
	say \$v;
	say "$v";
	# 输出:
	#   SCALAR(0x22f3d10)
	#   ---- before ----
	#   SCALAR(0x2277ab0)
	#   SCALAR(0x2277a98)
	#   SCALAR(0x2277b40)
	#   SCALAR(0x2277b58)
	#   ---- after ----
	#   SCALAR(0x22f3d10)
	#   3333
	```

### 数组相关函数

- push:数组尾部追加元素或列表,返回追加完后的数组长度

- pop:移除并返回数组最后一个元素

- shift:移除并返回数组第一个元素

- unshift:数组首部添加一个元素或列表,返回追加完后的数组长度

- keys:返回数组索引值

- values:返回数组元素值

- ```
	# splice
	1. splice @array:清空数组,返回被移除的元素
	2. splice @array,offset:删除offset处到末尾的所有元素,返回被移除的元素
	3. splice @array,offset,length:offset处开始向后删除length个元素,返回被移除的元素
	4. splice @array,offset,length,list:offset处开始向后删除length个元素,删除部分用list替代,返回被移除的元素
	offset为负数:删除从offset处,length个元素
	length为负数:保留length个参数
	# =================================================== #
	@arr=qw(perl py php shell ruby java c c++ js);
	@new_arr=splice @arr,2,-2;   # 从php开始删除,最后只保留c++和js两个元素
	say "original arr: @arr";    # 输出:perl py c++ js
	say "new arr: @new_arr";     # 输出:php shell ruby java c
	```

### 列表相关函数

- 1. 列表重复 x: my @arr = (1,2) x 3

- 2. join:列表元素用给定字符连接起来 join "-" qw(a b c e)

- 3. split:使用给定分隔符将字符串划分为列表,分隔符支持正则表达式

- ```
	#split usage
	split /PATTERN/,EXPR,LIMIT
	split /PATTERN/,EXPR
	split /PATTERN/
	split
	```

- reverse():返回列表反转数值,不改变列表原有顺序

- sort():返回列表重排后的数值,不改变列表原有顺序

## 条件判断语句

- ```
	if(cond_true) {
	  cmd;
	}elsif(cond_true) {
	  cmd;
	}else {
	  cmd;
	}
	```

- ```
	unless(com_fals) {
	  cmd;
	}
	# unless也可以接elsif/else,通常不会这样用
	```

- ```
	# 三元运算符
	cond? con_true:con_false;
	```

- ```
	# 实用的单行if mode
	say "Debug information" if($DEBUG_EN == 1);
	```

## 循环语句

- last:类似于break,跳出循环体

- next:类似于continue,跳过当前循环进入下一个循环

- redo:重新执行一遍循环体

- lable:

- ```
	# while语句
	while(cond_true) {
	  cmd;
	}
	```

- ```
	# until语句
	until(con_false) {
	  cmd;
	}
	```

- ```
	# for/foreach循环
	for (expr1; expr2; expr3) {
	  ...
	}
	foreach (expr1; expr2; expr3) {
	  ...
	}
	```

- ```
	# for/foreach遍历
	for my $i (LIST) {}
	for (LIST){}
	foreach my $i (LIST) {}
	foreach (LIST){}
	```

- ```
	# 纯语句块即单独一个大括号,只循环一次的循环结构
	{...}
	```

## 哈希

### 哈希赋值

- %hash_name:多个键值对数据的存储空间
- 使用胖逗号,尾部可以加上一个逗号方便扩展
- 使用胖逗号,key可以省略单引号(自动补上单引号)
- %hash_name = (key1,value1,key2,value2 ...);
- %hash_name = (key1 => "value1",key2 => "value2",);

### 判断哈希是否为空

- ```
	# hash have at least one key-value
	if(%hash_name){
	  say "This hash is not empty"
	}
	```

### 哈希数值遍历

- ```
	while(my ($key,$value) = each %hash_name){
	  say "The key $key value is $value";
	}
	
	foreach my $key (keys %hash_name){
	  say "The key $key value is $value";
	}
	
	for my $key (keys %hash_name){
	  say "The key $key value is $value";
	}
	```

### 哈希函数

- keys: my @k = keys %hash_name;返回键-列表
- values: my @v = values %hash_name;返回值-列表
- exists: exists $hash_name{'key'};键值对是否存在
- delete: delete $hash_name{'key'};删除键值对

## 引用

- 变量sigil符号前加上反斜线表示变量的引用

- 引用可以查看变量保存的数据的内存地址

- 不同类型的变量的引用,打印引用值结果也不同

- ```
	my $name = "junma";
	my @arr = qw(a b c);
	my %h = ( name => "junma", age  => 23 );
	
	say \$name;  # SCALAR(0x55ad7f974dc8)
	say \@arr;   # ARRAY(0x55ad7f974738)
	say \%h;     # HASH(0x55ad7fa99150)
	```

## 子程序

- ```
	sub sub_fun{
	    cmd;
	}
	
	sub sub_fun(){
	    cmd;
	}
	```

- ```
	#调用
	1. sub_fun;
	2. sub_fun();
	3. &sub_fun;
	4. &sub_fun();
	```

- 参数:子程序的参数会存放在@\_中,通过\$\_[0],$\_[1]等依次获取

## 正则表达式

### 匹配

- 正则匹配基本形式:string =~ /pattern/
- 正则匹配的严格形式:string =~ m/pattern/,使用双斜线时m可以省略
- m后面可以接其他成对的字符:m## m%% m() m!!来替换m//
- 正则表达式匹配的项是\$\_,则可以简写;**\$_ =~ /paattern/等价于 /pattern/**

### 替换

- 替换形式:s/match_text/new_text/
- 替换形式:tr/match_text/new_text/
- 替换形式:y/match_text/new_text/

### 匹配修饰字

- i: 不区分大小写
- s: dot元字符可以匹配换行符
- x: 忽略匹配项中的空格

### 替换修饰字

- g: 全局替换
- m:匹配多行
- e:替换并当作命令执行
- ee:两次替换并当作命令执行

## 文件读写

### 打开文件

- 语法格式:open FILE_HANDLE,"mode","file_path/file_name" or die "prompt message";采用三段式,通过句柄打开文件。
- r mode:read only
- w mode:write/create/truncate
- r+ mode:read/write
- w+ mode:read/write/create/truncate
- a mode:write/create/append
- a+ mode:read/write/create/truncate

### 读文件

- ```
	# line by line
	while(chomp(my $line = <FILE_HANDLE>)){
	    cmd;
	}
	```

- ```
	# store in an array
	chomp(my @array = <FILE_HANDLE>)
	```

- ```
	# store in a scalar
	 my $content;
	 open(my $fh, '<', $filename) or die "cannot open file $filename";
	 {
	     local $/;
	     $content = <$fh>;
	 }
	 close($fh);
	```

### 写文件

- ```
	# FILE_HANDLE不需要用引号包围
	# FILE_HANDLE和写入的字符间没有逗号/分号
	print FILE_HANDLE "strings that want write to file";
	printf FILE_HANDLE "strings that want write to file";
	say FILE_HANDLE "strings that want write to file";
	```

### 关闭文件

- close(FILE_HANDLE);

## 文件测试

- ```
	if(-r filename and -w ){
	}
	```

- ```
	if(-r -w filename){
	}
	```

- [file test operate reference webpage](https://www.geeksforgeeks.org/perl-file-test-operators/)

- -r	checks if the file is readable

- -w	checks if the file is writable

- -x	checks if the file is executable

- -o	checks if the file is owned by effective uid

- -R	checks if file is readable by real uid

- -W	checks if file is writable by real uid

- -X	checks if file is executable by real uid/gid

- -O	checks if the file is owned by real uid

- -e	checks if the file exists

- -z	checks if the file is empty

- -s	checks if the file has nonzero size (returns size in bytes)

- -f	checks if the file is a plain text file

- -d	checks if the file is a directory

- -l	checks if the file is a symbolic link

- -p	checks if the file is a named pipe (FIFO): or Filehandle is a pipe

- -S	checks if the file is a socket

- -b	checks if the file is a block special file

- -c	checks if the file is a character special file

- -t	checks if the file handle is opened to a tty

- -u	checks if the file has setuid bit set

- -g	checks if the file has setgid bit set

- -k	checks if the file has sticky bit set

- -T	checks if the file is an ASCII text file (heuristic guess)

- -B	checks if the file is a “binary” file (opposite of -T)

## 目录操作

- glob('dir_path/file_type')
- opendir(DIR_HANDLE,dir)
- @dir_list = readdir(DIR_HANDLE)
- closedir(DIR_HANDLE)
posted @ 2022-04-21 22:04  MOVIT  阅读(45)  评论(0)    收藏  举报