Perl语言入门14-17
---------第十四章 字符串与排序-------------------
index查找子字符串
my $stuff = "howdy world!";
my $where = index($stuff, "wor"); #6
#返回首个字符匹配的位置,字符串第一个位置为0,上例即wor匹配的w位置
#无法匹配返回-1
my $here = index($stuff,"w",2); #返回2(从2+1个字符开始)
my $there = index($stuff,"w",3); #返回6
rindex从末尾开始找起,基本用不到
substr操作子字符串
#第二个参数:起始位置,第三个参数:截取长度
my $minx = substr("fred J. Flintstone", 8, 5); #Flint
my $peb = substr "fred J. Flintstone", 13; #stone 不加第三个参数,默认到最后
my $out = substr("some very long string",-3,2); #in 倒数第三个字符开始
#与index结合使用
my $long = "some very very long string";
my $right = substr($long, index($long,"l"); #long string
#修改字符串
my $string = "hello, world";
substr($string, 0, 5) = "goodbye"; #goodbye, world 可见长度不一定相同
#替换
substr($string, -20) =~ s/fred/barney/g; #只替换字符串后20个中匹配字符
sprintf格式化字符串
不同于printf的是它能赋值给变量
my $date = sprintf "%4d %02d",$yr,$mo;
my $money = sprintf "%.2f",2.3456;
排序
#数组排序
my @numbers = sort {$a <=> $b} @some_numbers; #数值
my @string = sort {$a cmp $b} @some_strings; #字符串
my @descending = reverse sort {$a <=> $b} @some_numbers;
my @descending = sort {$b <=> $a} @some_numbers; #结果同上
#哈希值排序
sort keys %hash #这是对键排序
sort{$hash{$b} <=> $hash{$a}} keys %hash #值排序,降序
sort{$hash{$a} <=> $hash{$b}} keys %hash #升序
#sort values %hash ???
#先按值再按键排序
my @winner = sort by_score_name keys %score;
sub by_score_name{
$score{$b} <=> $score{$a} #根据分数降序排列
or
$a cmp $b #分数相同再按名字排序
}
#飞船操作符返回-1或1,都为真,两数相同时返回0。
#再加or,可进行多级排序
-------第十五章 智能匹配与given-when结构------------
智能匹配操作符~~
会根据两边操作数的数据类型自动判断何种方式进行比较和匹配,一般与前后顺序无关,特殊情况外。
say "I found fred in the same" if $name ~~ /Fred/;
对不同操作数的处理:
%a ~~ %b #键是否相等
%a ~~ @b 或@a ~~ %b #a键是否在数组b中
%a ~~ /fred/ 或/fred/ ~~ %b #键匹配
'fred' ~~ %a #哈希值$a{fred}是否存在
@a ~~ @b #数组是否相同
@a ~~ /fred/ #数组中至少一个元素匹配
$name ~~ /fred/ #模式匹配
'fred' ~~ 'fred' #字符串是否相同
123 ~~ 456 #数组是否相等
示例1:%names中是否匹配fred键,若有打印
#传统写法:
my $flag = 0;
foreach my $key (keys %name){
next unless $key =~ /fred/;
$flag = $key;
last;
}
print "the key is $flag\n" if $flag;
#智能匹配:
say "sucess" if %names ~~ /fred/; #或if /fred/ ~~ %names
示例2:判断两个等长的数组是否完全相同
#传统写法:
my $equal = 0;
foreach my $index (0..$#names1){
last unless $names1[$index] eq $names[$index];
$equal++;
}
print "yes\n" if $equal == @names1;
#智能匹配:
say "yes" if @names1 ~~ @names2;
- given语句
given-when多条件,类似c语言switch语句。
given ($ARGV[0]){
when('fred'){say "1"} #实际是$_ =~ 或$_ ~~
when(/Fred/i){say "2"}
when(/\AFred/){say "3"}
default {say "4"}
}
#和if-elsif-else语句的区别在于:given-when可在满足某条件的基础继续测试其他条件,而if-else-elsif-else则非此即彼。
#每个条件也可加break/continue等控制
多个条目的when匹配
将given放到foreach中循环测试
foreach my $name(@names){
given($name){
...
}
}
##可简化以下形式:
foreach(@names){ #不使用具名控制变量
say "\nProcessing $_";
when('fred'){say "1"; continue} #continue使每个条件都能执行
when(/Fred/i){say "2"; continue}
when(/\AFred/){say "3"}
say "moving on to default...";
default {say "4"}
}
----------第十六章 进程管理----------------------
system函数
perl程序为父进程,system为子进程。
#一般就是shell命令。
system 'date';
system 'ls -l $HOME';
#此处用双引号,会将$HOME视为变量内插,而非环境变量
system 'for i in *; do echo ==$i==; cat $i; done &';
#里面的命令为孙进程;&放后台运行,perl程序无需等待它运行完
#不使用shell命令,则用多参数:
system 'tar','cvf',$tarfile, @dirs;
环境变量
%ENV : 每个键都代表一个环境变量
$ENV{'PATH'} = "/home/rootbeer/bin:$ENV{'PATH'}";
其他类system函数和命令
#1.exec函数
exec 'date';
#不能在后台运行,一般很少用
#2. 反引号
print "the time is now: ", `date`;
my $out_errors = `frobnitz -enable 2>&1`; #将标准错误合并至标准输出
#建议如果不需要捕获输出内容,就不要用反引号。
#3. qx操作符
qx(perldoc -t -f int) #近似反引号
#建议还是用system函数
------第十七章 高级Perl技巧-------------------
切片
#标量:
my $count = (split /:/)[5];
my($card,$count) = (split /:/)[1,5];
my($first, $last) = (sort @names) [0,-1] #取第一个和最后一个
#数组切片:
my @num = @names[9,2,1,0,1];
#下标可任意顺序,也可重复
#哈希切片:
my @three_scores = @score { qw/barney fred dino/ }
#等于:my @three_scores = ($score{"barney"}, $score{"fred"}, $score{"dino"});
my @name = qw /a b c/;
my @math_score = qw /1 2 3/;
@score{@name} = @math_score; #相当于构建哈希
print "their scores were: @score{@name}\n"; #也能内插
捕获错误
- eval表达式
检查到致命错误立即停止运行整个eval块,退出后继续运行其余代码。
默认返回语句块最后一条表达式结果。若捕获到错误,整个语句块返回undef,并在特殊变量$@中设置错误消息。
#如对除0错误的处理:
my $barney = eval {$fred/$dino} // 'NaN'; #将NaN设为默认值
print "I can't divide by \$dino : $@" if $@;
#检查返回值来判断
unless (eval { $fred/$dino}){
print "I can't divide by \$dino : $@" if $@;
}
#对多处潜在(打开文件/除0/子程序等)的致命错误做防范:
foreach my $person (qw /one wtow three four/){
eval{
open my $fh, '<', $person or die "can't open file: $!";
my ($total, $count);
while(<$fh>){
$total += $_;
$count++;
}
my $average = $total/$count; #eval也可在此嵌套
print "average for file $person was $average\n";
&do_something($person,$average);
}
if($@){
print "an error occurred ($@),continuing\n";
}
}
#但有些错误是eval无法捕获的:
#如语法错误;perl解释器崩溃;警告信息;exit操作符
高级错误处理
Perl语言处理错误的基本做法:用die抛出异常,用eval捕获异常,通过识别$@中的错误消息判断问题出在哪里。
#local $@;
eval{
...;
die "a unexpected message" if $unexpected;
die "bad denominator" if $dino == 0;
$barney = $fred/$dino;
}
if( $@ =~ /unexpected/){...;}elsif($@ =~ /denominator/){...;}
#这类代码有很多弊端,如$@的动态作用域问题,确保不干扰高层eval错误。
#这里最好在最前加上local $@;
#Try::Tiny模块解决这类问题:
use Try::Tiny;
try{...;} #可能抛出异常的代码
catch{...;} #处理异常的代码
finally{...;} #不管是否出错都运行的代码
my $barney =
try{$fred/$dino}
catch{say "error is $_";} #$_替代$@,避免干扰
finally{say @_? 'error' : 'worked';}; #@_判断参数内容
#autodie:
#perl自带autodie编译指令,自动抛出异常
use autodie;
open my $fh, '>', $filename;
grep函数处理列表元素
返回真假值
my @odd_numbers = grep { $_ % 2} 1..1000; #挑出奇数
my @match_lines = grep {/\bfred\b/i} <$fh>;
my @match_lines = grep /\bfred\b/i/, <$fh>;
#若只有一个表达式,可去掉大括号加逗号进行简化
my $line_count = grep /\bfred\b/i, <$fh>; #标量,返回匹配个数
map函数处理列表元素
返回实际结果
my @data = (4.5,6.23,67);
my @format_data = map {&big_money} @data; #对金额数字格式化
print "the money are: \n", map {sprintf("%25s\n", $_)} @format_data;
#简单表达式同样可简化:
print "some powers of two are:\n",
map "\t".(2**$_)."\n", 0..15;
其他处理列表元素函数
Perl自带的List::Util模块
#first函数:
my $first_match = first {/\bfred\b/i} @names;
#sum函数
my $total = sum(1..100);
#max函数
my $max = max(3,5,4,7);
#maxstr函数:最长字符串
my $max = maxstr(@strings);
#shuffle函数:对列表元素随机排序
my @shuffled = shuffle(1..1000);
List::MoreUtils模块
#none/any/all函数
if(none {$_>100} @numbers){...;}
elsif(any {$_ >50} @numbers){...;}
elsif(all {$_ <10} @numbers){...;}
#natatime函数(n at a time,同时处理n组)
my $iterator = natatime 3, @array;
#mesh函数:合并多个列表(交错填充)
my @large_array = mesh @one, @two, @three;
Perl语言入门14-17的更多相关文章
- Perl语言入门: 斜线不是元字符,所以在不作为分隔符时不需要加上反斜线。
Perl语言入门: 斜线不是元字符,所以在不作为分隔符时不需要加上反斜线.
- Perl语言入门
Perl 是 Practical Extraction and Report Language 的缩写,可翻译为 "实用报表提取语言". Perl语法基础: (1)Perl程序由声 ...
- Perl语言入门:第六章习题:处理用户所指定的名字并汇报相应的姓。
37 print "\n----------------------------------_exercise_6_1--------------------------\n"; ...
- Perl 语言入门6-9
---- 第6章 哈希----------- 简介 键值对.键和值都是任意标量,但键总是会被转换成字符串. 键唯一,值可重复. 应用场景:一组数据对应到另一组数据时. 如找出重复/唯一/交叉引用/查表 ...
- Perl语言入门(中文版)(第6版) 东南大学出版社
第一章简介 问题与答案 这本书适合你吗? 为何有这么多的脚注? 关于习题和解答? 习题前标的数字是什么意思? 如果我是Perl讲师? “Perl”这个词表示什么意思? Larry为什么要创造Perl? ...
- Perl 语言入门1-5
第一章 简介 perl -v 文字处理,编写小型CGI脚本(Web服务器调用程序)的最佳语言 CPAN: Perl综合典藏网 shebang: #! /usr/bin/perl 或#! /usr/lo ...
- Perl语言入门--3--文件读取与写入
现有文件test.txt,内容为:"123\n456" 1,打开文本test.txt #!/usr/bin/perl open d,"test.txt"; d ...
- Perl语言入门--4--列表
1.列表也是数组的形式:(1,'a',2,3,4) 元素可以是任意类型,变量,表达式 2.空列表:() 单元素列表:(2) .与值2不同 qw(1 $a str) #qw是用空格作为分隔符,元素 ...
- Perl语言入门--2--perl的运算符
一.算数运算符 **:是幂 结果不能超过数的范围 当指数为小数时 底数不能为负数 %:取余数 两边的操作数为整数,如果不是则要截取,把所有的小数部分去掉 注意:当一个字符串参加运算,需要转化为整数时 ...
随机推荐
- Linux主机入侵检测
检查系统信息.用户账号信息 ● 操作系统信息 cat /proc/version 用户信息 用户信息文件 /etc/passwd root:x:0:0:root:/root:/bin/bash 用户名 ...
- Codeforces1575D
思路分析 此题采用dfs,注意X选中了之后所有的X值相同,所以需要一个flag来存储X的值. 注意前导0要单独讨论,然后就是当'X'或者'_'在第一位时不能选0,其它位可以选0 - 9 任意一个数. ...
- 在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务
在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务 https://procodeguide.com/programming/polly-in-aspnet-core ...
- Convolutional Neural Network-week2编程题2(Residual Networks)
1. Residual Networks(残差网络) 残差网络 就是为了解决深网络的难以训练的问题的. In this assignment, you will: Implement the basi ...
- SpringBoot加密配置属性
一.背景 在系统中的运行过程中,存在很多的配置属性,比如: 数据库配置.阿里云配置 等等,这些配置有些属性是比较敏感的,是不应直接以明文的方式出现在配置文件中,因此对于这些配置我们就需要加密来处理. ...
- Linux有什么可取之处竟如此受欢迎
什么是Linux? Linux是一个操作系统软件.和Windows不同的是,Linux是一套开放源代码程序的.并可以自由传播的类Unix操作系统,它是一个支持多用户.多任务.多线程和多CPU的操作系统 ...
- 常用Java API:大数类
摘要 java中的基础数据类型能存储的最大的二进制数是 2 ^ 63 - 1, 对应的十进制数是9223372036854775807,也就是说只要运算过程中会超过这个数,就会造成数据溢出,从而造成错 ...
- 设计AOV网拓扑排序的算法
拓扑排序 对一个有向图构造拓扑序列的过程称为拓扑排序(不唯一) 思想 从AOV网选择一个没有前驱的顶点并输出 从AOV网中删去该顶点,并且删去所有以该顶点为尾的弧 重复上述两步,直到全部顶点都被输出, ...
- 【数据结构&算法】02-复杂度分析之执行效率和资源消耗
目录 前言 复杂度 分析方法 大 O 复杂度表示法 例子-评估累加和的各种算法执行效率 算法 1(for 循环): 算法 2(嵌套 for 循环): 大 O 表示 时间复杂度分析 关注执行最多的一段代 ...
- 关于docker中容器可以Ping通外网,真机无法Ping通容器的问题
首先我们要知道整体的框架结构,docker是我们安装在centos7上的,而centos7是安装在vmware上.其中docker中还有若干容器运行. 整体框架图如下: 我们将它分为两部分,一部分是d ...