正则表达式――perl模式匹配
Practiacl Extraction
and Report Language
一.模式匹配操作符
1.tr/ /
/ 替换操作符不支持正则表达式 也不具备双引号替换能力
m/ / s/ /
/ 都支持正则表达式,并且可以提供或限制双引号替换能力(当用单引号作为操作符时则不具备变量替换能力)
s/ / / , tr/ /
/ 可以用两组不同的括号进行分割,以保证格式清晰s(good)
2.绑定操作符
=~
, !~,m/ / s/ / / tr/ /
/ 都支持
绑定操作符的优先级非常高
3. perl
特有的全局变量
1. $` , $& ,
$’ 分别存有匹配内容左,匹配内容,匹配内容右的内容
2.
可以用()捕获特定的模式 并依次存入 $1 $2
$3 中
二.模式修饰词
m/ / s/ /
/ 和 tr/ / / 的修饰词不同
/i
忽略字母大小写
/s /m
允许模式中存在换行符 (一般模式中不允许存在换行符)
/x
允许模式中换行,并表明注释,使正则表达式更易读
/o
只编译一次,针对模式中的变量代换
/g
无穷匹配
/e
修饰词把 REPLACEMENT 当作一个
Perl 代码块,而不仅仅是一个替换的字串。执行这段代码后得出的结果当作替换字串使用。
my $str = "hello chinaUnix i am wlj
!";$str =~ s/(s+)/length($1) == 1 ? $1 : '_' x length($1)/eg;#$str =~ s/(s{2,})/'_'x
length($1)/eg;print "$str ";##------结果--------------------hello_____chinaUnix i am wlj___!
三.m/ / 匹配
1.分隔符
用 ? 或 ‘ 作分隔符时有特殊的含义
m??
表示只匹配一次
m’ ‘ 表示禁止变量替换和六种转换
2.返回值
标量环境里 匹配成功返回 1 ,失败 返回 0
列表环境里, 返回子字串的列表,并捕获()中的模式
( $key,$value) =~ m/(/w+:(/.*)/
;
/g 修饰词的返回值
列表环境 : 返回所有匹配字串的列表
如: my @perls = $string =~ m/perl/ig
;
如果有捕获圆括号,则返回捕获到的字串
如: 用字串 $string = “password=xyzzy verbose= 9
score=0”
初始化下面的散列:%hash = {password =>
“xyzzy”, verbose => 9,
socre=>0};
%hash = $string =~ /(/w+)=(/w+)/g ;
# 利用列表环境下匹配得到数组,再通 #
过数组对散列hash赋值
标量环境中
/g表示一次渐进的匹配,它令perl从上一次匹配停下来的位置开始一次新的匹配
如: while (/perl/g) { print “ $&
/n”};
# 需求举例
# 求出0- 300 中出现过多少次数字9
#use strict;my $num = 0;foreach (0..300)
{$num
+= $_ =~ s/9//g;
"$num ";
三.s/ /
/ 操作符(替换)
返回值:
标量环境里返回值是成功替换的次数
替换部分被当作双引号看待可进行变量转换,而且可以使用前半部分模式匹配得到的变量$1,$2,$3
$&,等
新的修饰词
/e
把右边当作一个表达式计算
利用s/ / / 修改字串的用法
1.($newStr = $oldStr)=~ s/good/bad/g
2.替换数组的每一个元素:
For (@newArray,@oldArray)
{s/$_/newStr/g}
3.用单程循环对同一个变量重复替换
For ($string)
{
s/^/s//;
# 丢弃开头的空白
s//s$//;
# 丢弃结尾的空白
s//s+//g; # 丢弃中间的空白
}
4.把逗号放到整数的合理位置
$_ =
“12345678”;
1 while
s/(/d)(/d/d/d)(?!/d)/$1,$2/;
Print “$_ /n” # 输出: 12,345,678
四.Tr/ / / 操作符 (转换)
1.tr
不支持正则表达式 和 变量替换,只是一种单纯的划定范围的替换
尽管不支持变量替换,但可以用eval
expr实现
$count = eval
“tr/$oldStr/$newStr/”;
Die if $@;
如果仅仅是转换大小写
不要使用tr/ / / 建议使用双引号里的 转移字符 /U /L 类似的uc lc 函数
2.修饰词,与m/ / s/ /
/ 的修饰词不同
/c 与searchlist 为补
/s 消除重复的字符
/d 删除找到的但没有替换的字符 ,任何再searchlist 中声明但再replacement没有给出替换的字符将被删除。
如果没有/d 修饰词,那么
1),replacement 比 searchlist 短,则将复制replacement最后一个字符直到足够长
2),replacement 为空,则 replacement = searchlist
可以用此用法统计次数和/s 压缩
$string
=~ tr/a-zA-Z//s # bookkeeper ->
bokeper
五.元字符
12个元字符
/ | ( ) [ { ^ $ * +
?
^ : 在字符集中 ^ 表示补集 [^1,2,3] 除了1,2,3
在一般的模式中表示 以什么开头
$ : 表示以什么结尾
六.量词
分为最大量词,最小量词(由?控制)
1.最大量词
* 匹配0 或更多次
+ 匹配1 或更多次
? 匹配 1 或 0 次
{count}匹配count次
{min,}
匹配至少min次
{min,max}
匹配至少 min次,但不超过max次
2.最小量词
*?
匹配0次或更多次
+?匹配1次或更多次
??匹配0次或1次
{min,}? 匹配最多min次
{min,max}? 匹配至少min次,但不超过max次
七.常用的字母数字正则元符号
.
通配符匹配除了换行符外的任何单字符(如果加上修饰词/s 也可以匹配换行符)
/d
数字 [0-9]
/D
非数字
/s
空格
/S
非空格
/w
字 [a-zA-Z0-9_]
/W
非字
/E
结束大小写或掩码
/l
把下一个字符变成小写 /u 大写
/L
把/E以前的字母都变成小写
/U 大写 如:s/revision//u$&/g;
#########################################################################
#
#
论坛实际问题及零散知识点
#
###########################################################################
1.正则匹配的特殊变量
@-
最近一次正则表达式匹配的部分在目标字串中的起始偏移量
@+
最近一次正则表达式匹配的部分在目标字串中的终止偏移量
$&
最近一次正则表达式匹配到的部分
$`
在目标字串中最近一次正则表达式匹配到的部分之前的内容
$'
在目标字串中最近一次正则表达式匹配到的部分之后的内容
$`
is the same as substr($var,
0,
$-[0])
$& is the
same as substr($var,
$-[0],
$+[0] -
$-[0])
$'
is the same as substr($var,
$+[0])
$1
is the same as substr($var,
$-[1],
$+[1] -
$-[1])
$2
is the same as substr($var,
$-[2],
$+[2] -
$-[2])
$3
is the same as substr($var,
$-[3],
$+[3] -
$-[3])
#
正则匹配 特殊变量测试代码
#
#!/usr/bin/perluse strict;use warnings;my
$str = "abcedfabcertfabciruabc";while ($str =~ /(abc)/g)
{ # 注意捕获匹配的小括号不能少print "$-[1] -- $+[1]
"; # 也可以是print "$-[0] -- $+[0]
"$` -- $& --
$' ";
}#
运行结果bash-2.03$
testString.pl0 -- 3-- abc -- edfabcertfabciruabc6 -- 9abcedf --
abc -- ertfabciruabc13 -- 16abcedfabcertf --
abc -- iruabc19 -- 22abcedfabcertfabciru -- abc -- my
$str = "abcedfabcertfabciruabc";if ($str =~ /(^abc)w+(abc)w+(abc)w+(abc$)/g)
"$-[0] -- $+[0]
"; # $-[0],$+[0] 存储的是整个正则表达式匹配的部分的起始和结束坐标
print "$-[1] -- $+[1]
"; # 与小括号捕获的无关print "$-[2] -- $+[2]
";print "$-[3] -- $+[3]
";print "$-[4] -- $+[4]
";print "$`--$&--$'
"; ##
$` $&, $' 存储的是正则表达式匹配到的自符。及其左右。}## 运行结果bash-2.03$
testString.pl0 -- 220 -- 36 -- 913 -- 1619 -- 22--abcedfabcertfabciruabc-- ##
$` $&, $' 存储的是正则表达式匹配到的自符。及其左右。
日志分析需求代码:
#############
# 切出两行对齐部分
#############
#uniqu- TCACAACATGGTATCAGAGCAGGT#TA4806
ACTCTGTTTTTCTTCTCTCTCTCAATAATCCAACATGGTATCAGAGCCGATGGTTGTCCT
#
#
#uniqu- TCACAACATGGTATCAGAGCAGGT#TA4891
TATCTTCTTCTCCGTAACAAACTCTTCTGTAACATGGTATCAGAGCATGAATGGTGAATCuse strict;use warnings;my $UrFile = "/shvpn/test/wlj/perl/substr.log";open(FILE,"
"Can't open the file :
$! ";my($slength,$swidth,$spaces);while(){# chomp;if (/^s*$/)
{ # 匹配空行print "$_";
}elsif(/^uniqu/){chomp; # 每行都会有回车结尾,先去除if(/w+s*$/){$slength=$-[0];
获取匹配字串的起始坐标$swidth=length($&);
}$spaces=" "x$slength; # x用法print $spaces,$&," ";
}else{if(/^S/){chomp;my $string=substr($_,$slength,$swidth);print $spaces,$string," ";
}
}
}close
FILE;## 运行结果bash-2.03$
logAnalyse.pl
TCACAACATGGTATCAGAGCAGGTCAATAATCCAACATGGTATCAGAGTCACAACATGGTATCAGAGCAGGTTCTTCTGTAACATGGTATCAGAGC
一 常规表达式中,/pattern/常用到的语法
/pattern/ 结果
除了换行字符 外,找寻只有一个字符的字符串
x? 找寻0个或是1个x字符
x* 找寻0个或是0个以上的x字符
.* 找寻0个或是0个以上的任何字符
x+ 找寻0个或是1个以上的x字符
.+ 找寻1个或是1个以上的任何字符
{m} 找寻刚好是m个个数指定的字符
{m,n} 找寻在m个数个数以上,n个个数以下指定的字符
{m,} 找寻m个个数以上指定的字符
〔〕 找寻符合〔〕内的字符
〔^〕 找寻不符合〔〕内的字符
〔0-9〕 找寻符合0到9的任何一个字符
〔a-z〕 找寻符合a到z的任何一个字符
〔^0-9〕 找寻不符合0到9的任何一个字符
〔^a-z〕 找寻不符合a到z的任何一个字符
^ 找寻字符开头的字符
$ 找寻字符结尾的字符
d 找寻一个digit(数字)的字符,和〔0-9〕语法一样
d+ 找寻一个digit(数字)以上的字符串,和〔0-9〕+语法一样
D 找寻一个non-digit(非数字)的字符,和〔^0-9〕语法一样
D+ 找寻一个non-digit(非数字)以上的字符,和〔^0-9〕+语法一样
w 找寻一个英文字母或是数值的字符,和〔a-zA-Z0-9〕语法一样
w+ 找寻一个以上英文字母或是数值的字符,和〔a-zA-Z0-9〕+语法一样
W 找寻一个非英文字母,数值的字符,和〔^a-zA-Z0-9〕语法一样
W+ 找寻一个以上非英文字母,数值的字符,和〔^a-zA-Z0-9〕+语法一样
s 找寻一个空白的字符,和〔 f〕一样
s+ 找寻一个以上空白的字符,和〔 f〕+一样
S 找寻一个非空白的字符,和〔^ f〕一样
S+ 找寻一个以上非空白的字符,和〔^ f〕+一样
找寻一个不以英文字母,数值为边界的字符串
B 找寻一个以英文字母,数值为边界的字符串
a|b|c 找到符合a字符或是b字符或是c字符的字符串
abc 找到一个含有abc的字符串
(pattern) ()这个符号是会记忆所找寻到的字符,是一个很实用的语法
第一个()内所找到的字符串变成$1这个变量或是1变量
第二个()内所找到的字符串变成$2这个变量或是2变量
以此类推,笔者会在下一小节中详细介绍它的用法
/pattern/i i这个参数是代表忽略英文大小写的意思,也就是在找寻字符 串的时候,不会去考虑英文的大小写
如果要在pattern模式中找寻一个有特殊的意义的字符,要在 这个字符前加上这个符号,这样才会让这个特殊字符失效。
二 常规表达式(Regular Expression)的简单范例
看了上一小节文字处理模(Regular
Expression)之的,初学者对于这个语法的应用可能还不是很清楚,所以笔者会在这一小节中,举出一些在常规表达式中常用的范例给大家看看:
范例 说明
/perl/ 找到含有perl的字符串
/^perl/ 找到开头是perl的字符串
/perl$/ 找到结尾是perl的字符串
/c|g|i/ 找到含有c或g或i的字符串
/cg{2,4}i/ 找到c后面跟着2个到4个g,再跟着i的字符串
/cg{2,}i/ 找到c后面跟着2个以上g,再跟着i的字符串
/cg{2}i/ 找到c后面跟着2个g,再跟着i的字符串
/cg*i/ 找到c后面跟着0个或多个g,再跟着i的字符串,如同/cg{0,1}i/
/cg+i/ 找到c后面跟着一个以上g,再跟着c的字符串,如同/cg{1,}i/
/cg?i/ 找到c后面跟着0个或是一个g,再跟着c的字符串,如同/cg{0,1}i/
/c.i/ 找到c后面跟着一个任意字符,再跟着i的字符串
/c..i/ 找到c后面跟着二个任意字符,再跟着i的字符串
/〔cgi〕/ 找到符合有这三个字符任意一个的字符串
本文和大家重点讨论一下Perl模式匹配的概念,Perl模式的用法如结合函数split将字符串用某Perl模式分成多个单词:@array=split(//,$line),相信通过本文的学习你对Perl模式的用法有深刻的了解。
一、Perl模式匹配选项
选项描述
g匹配所有可能的Perl模式
i忽略大小写
m将串视为多行
o只赋值一次
s将串视为单行
x忽略Perl模式中的空白
1、匹配所有可能的Perl模式(g选项)
@matches="balata"=~/.a/g;#now@matches=("ba","la","ta")
匹配的循环:
while("balata"=~/.a/g){
$match=$&;
print("$match\n");
}
结果为:
ba
la
ta
当使用了选项g时,可用函数pos来控制下次匹配的偏移:
$offset=pos($string);
pos($string)=$newoffset;
2、忽略大小写(i选项)例
/de/i匹配de,dE,De和DE。
3、将字符串看作多行(m选项)
在此情况下,^符号匹配字符串的起始或新的一行的起始;$符号匹配任意行的末尾。
4、只执行一次变量替换例
$var=1;
$line=;
while($var<10){
$result=$line=~/$var/o;
$line=;
$var++;
}
每次均匹配/1/。
5、将字符串看作单行例
/a.*bc/s匹配字符串axxxxx\nxxxxbc,但/a.*bc/则不匹配该字符串。
6、在Perl模式中忽略空格
/\d{2}([\W])\d{2}\1\d{2}/x等价于/\d{2}([\W])\d{2}\1\d{2}/。
二、替换操作符
语法为s/pattern/replacement/,其效果为将字符串中与pattern匹配的部分换成replacement。如:
$string="abc123def";
$string=~s/123/456/;#now$string="abc456def";
在替换部分可使用Perl模式次序变量$n,如s/(\d+)/[$1]/,但在替换部分不支持Perl模式的特殊字符,如{},*,+等,如s/abc/[def]/将把abc替换为[def]。
替换操作符的选项如下表:
选项描述
g改变Perl模式中的所有匹配
i忽略Perl模式中的大小写
e替换字符串作为表达式
m将待匹配串视为多行
o仅赋值一次
s将待匹配串视为单行
x忽略Perl模式中的空白
注:e选项把替换部分的字符串看作表达式,在替换之前先计算其值,如:
$string="0abc1";
$string=~s/[a-zA-Z]+/$&x2/e;#now$string="0abcabc1"
三、翻译操作符
这是另一种替换方式,语法如:tr/string1/string2/。同样,string2为替换部分,但其效果是把string1中的第一个字符替换为string2中的第一个字符,把string1中的第二个字符替换为string2中的第二个字符,依此类推。如:
$string="abcdefghicba";
$string=~tr/abc/def/;#nowstring="defdefghifed"
当string1比string2长时,其多余字符替换为string2的最后一个字符;当string1中同一个字符出现多次时,将使用第一个替换字符。
翻译操作符的选项如下:
选项描述
c翻译所有未指定字符
d删除所有指定字符
s把多个相同的输出字符缩成一个
如$string=~tr/\d//c;把所有非数字字符替换为空格。$string=~tr/\t//d;删除tab和空格;$string=~tr/0-9//cs;把数字间的其它字符替换为一个空格。
四、扩展Perl模式匹配
PERL支持PERL4和标准UNIXPerl模式匹配操作所没有的一些Perl模式匹配能力。其语法为:(?pattern),其中c是一个字符,pattern是起作用的Perl模式或子Perl模式。
1、不存贮括号内的匹配内容
在PERL的Perl模式中,括号内的子Perl模式将存贮在内存中,此功能即取消存贮该括号内的匹配内容,如/(?:a|b|c)(d|e)f\1/中的\1表示已匹配的d或e,而不是a或b或c。
2、内嵌Perl模式选项
通常Perl模式选项置于其后,有四个选项:i、m、s、x可以内嵌使用,语法为:/(?option)pattern/,等价于/pattern/option。
3、肯定的和否定的预见匹配
肯定的预见匹配语法为/pattern(?=string)/,其意义为匹配后面为string的Perl模式,相反的,(?!string)意义为匹配后面非string的Perl模式,如:
$string="25abc8";
$string=~/abc(?=[0-9])/;
$matched=$&;#$&为已匹配的Perl模式,此处为abc,而不是abc8
4、Perl模式注释
PERL5中可以在Perl模式中用?#来加注释,如:
if($string=~(?i)[a-z]{2,3}(?#matchtwoorthreealphabeticcharacters)/{
...
}
本文和大家重点讨论一下Perl模式匹配的概念,Perl模式指在字符串中寻找的特定序列的字符,由反斜线包含:/def/即Perl模式def。其用法如结合函数split将字符串用某Perl模式分成多个单词:@array=split(//,$line),请看本文详细介绍。
Perl模式匹配
一、Perl模式简介
Perl模式指在字符串中寻找的特定序列的字符,由反斜线包含:/def/即Perl模式def。其用法如结合函数split将字符串用某Perl模式分成多个单词:@array=split(//,$line);
二、匹配操作符=~、!~
=~检验匹配是否成功:$result=$var=~/abc/;若在该字符串中找到了该Perl模式,则返回非零值,即true,不匹配则返回0,即false。!~则相反。
这两个操作符适于条件控制中,如:
if($question=~/please/){
print("Thankyouforbeingpolite!\n");
}
else{
print("Thatwasnotverypolite!\n");
}
三、Perl模式中的特殊字符
PERL在Perl模式中支持一些特殊字符,可以起到一些特殊的作用。
1、字符+
+意味着一个或多个相同的字符,如:/de+f/指def、deef、deeeeef等。它尽量匹配尽可能多的相同字符,如/ab+/在字符串abbc中匹配的将是abb,而不是ab。
当一行中各单词间的空格多于一个时,可以如下分割:
@array=split(/+/,$line);
注:split函数每次遇到分割Perl模式,总是开始一个新单词,因此若$line以空格打头,则@array的第一个元素即为空元素。但其可以区分是否真有单词,如若$line中只有空格,则@array则为空数组。且上例中TAB字符被当作一个单词。注意修正。
2、字符[]和[^]
[]意味着匹配一组字符中的一个,如/a[0123456789]c/将匹配a加数字加c的字符串。与+联合使用例:/d[eE]+f/匹配def、dEf、deef、dEdf、dEEEeeeEef等。^表示除其之外的所有字符,如:/d[^deE]f/匹配d加非e字符加f的字符串。
3、字符*和?
它们与+类似,区别在于*匹配0个、1个或多个相同字符,?匹配0个或1个该字符。如/de*f/匹配df、def、deeeef等;/de?f/匹配df或def。
4、转义字符
如果你想在Perl模式中包含通常被看作特殊意义的字符,须在其前加斜线""。如:/\*+/中\*即表示字符*,而不是上面提到的一个或多个字符的含义。斜线的表示为/\\/。在PERL5中可用字符对\Q和\E来转义。
5、匹配任意字母或数字
上面提到Perl模式/a[0123456789]c/匹配字母a加任意数字加c的字符串,另一种表示方法为:/a[0-9]c/,类似的,[a-z]表示任意小写字母,[A-Z]表示任意大写字母。任意大小写字母、数字的表示方法为:/[0-9a-zA-Z]/。
6、锚Perl模式
锚描述
^或\A仅匹配串首
$或\Z仅匹配串尾
\b匹配单词边界
\B单词内部匹配
例1:/^def/只匹配以def打头的字符串,/$def/只匹配以def结尾的字符串,结合起来的/^def$/只匹配字符串def(?)。\A和\Z在多行匹配时与^和$不同。
例2:检验变量名的类型:
if($varname=~/^\$[A-Za-z][_0-9a-zA-Z]*$/){
print("$varnameisalegalscalarvariable\n");
}elsif($varname=~/^@[A-Za-z][_0-9a-zA-Z]*$/){
print("$varnameisalegalarrayvariable\n");
}elsif($varname=~/^[A-Za-z][_0-9a-zA-Z]*$/){
print("$varnameisalegalfilevariable\n");
}else{
print("Idon'tunderstandwhat$varnameis.\n");
}
例3:\b在单词边界匹配:/\bdef/匹配def和defghi等以def打头的单词,但不匹配abcdef。/def\b/匹配def和abcdef等以def结尾的单词,但不匹配defghi,/\bdef\b/只匹配字符串def。注意:/\bdef/可匹配$defghi,因为$并不被看作是单词的部分。
例4:\B在单词内部匹配:/\Bdef/匹配abcdef等,但不匹配def;/def\B/匹配defghi等;/\Bdef\B/匹配cdefg、abcdefghi等,但不匹配def,defghi,abcdef。
7、Perl模式中的变量替换
将句子分成单词:
$pattern="[\\t]+";
@words=split(/$pattern/,$line);
8、字符范围转义
E转义字符描述范围
\d任意数字[0-9]
\D除数字外的任意字符[^0-9]
\w任意单词字符[_0-9a-zA-Z]
\W任意非单词字符[^_0-9a-zA-Z]
\s空白[\r\t\n\f]
\S非空白[^\r\t\n\f]
例:/[\da-z]/匹配任意数字或小写字母。
9、匹配任意字符
字符"."匹配除换行外的所有字符,通常与*合用。
10、匹配指定数目的字符
字符对{}指定所匹配字符的出现次数。如:/de{1,3}f/匹配def,deef和deeef;/de{3}f/匹配deeef;/de{3,}f/匹配不少于3个e在d和f之间;/de{0,3}f/匹配不多于3个e在d和f之间。
11、指定选项
字符"|"指定两个或多个选择来匹配Perl模式。如:/def|ghi/匹配def或ghi。
例:检验数字表示合法性
if($number=~/^-?\d+$|^-?0[xX][\da-fa-F]+$/){
print("$numberisalegalinteger.\n");
}else{
print("$numberisnotalegalinteger.\n");
}
其中^-?\d+$匹配十进制数字,^-?0[xX][\da-fa-F]+$匹配十六进制数字。
12、Perl模式的部分重用
当Perl模式中匹配相同的部分出现多次时,可用括号括起来,用\n来多次引用,以简化表达式:
/\d{2}([\W])\d{2}\1\d{2}/匹配:
12-05-92
26.11.87
070492等
注意:/\d{2}([\W])\d{2}\1\d{2}/不同于/(\d{2})([\W])\1\2\1/,后者只匹配形如17-17-17的字符串,而不匹配17-05-91等。
13、转义和特定字符的执行次序
象操作符一样,转义和特定字符也有执行次序:
特殊字符描述
()Perl模式内存
+*?{}出现次数
^$\b\B锚
|选项
14、指定Perl模式定界符
缺省的,Perl模式定界符为反斜线/,但其可用字母m自行指定,如:
m!/u/jqpublic/perl/prog1!等价于/\/u\/jqpublic\/perl\/prog1/
注:当用字母'作为定界符时,不做变量替换;当用特殊字符作为定界符时,其转义功能或特殊功能即不能使用。
15、Perl模式次序变量
在Perl模式匹配后调用重用部分的结果可用变量$n,全部的结果用变量$&。
Perl中我们有时需要调用shell命令,现在总结一下可以采用的集中方法吧。
1. system(”command”);
使用该命令将开启一个子进程执行引号中的命令,父进程将等待子进程结束并继续执行下面的代码。
2. exec(”command”);
效果同system命令类似,区别是不会开启子进程,而是取代父进程,因此执行完引号中的命令后进程即结束。一般和fork配合使用。
3. `command`;
使用反引号调用外部命令能够捕获其标准输出,并按行返回且每行结束处附带一个回车。反引号中的变量在编译时会被内插为其值。
4. open LIST “ls -l|”;
open MORE “|more”;
@list=;
print MORE @list;
close(LIST);
close(MORE);
使用带管道的文件句柄来执行外部命令,使用方式与读写文件类似。可以从外部命令的输出读取数据,也可以将数据输出到外部命令作为输入。
5. defined(my $pid=fork) or die “Can not fork: $!\n”;
unless ($pid) {
exec (”date”);
}
waitpid ($pid,0);
使用fork将会开启子进程与父进程同时执行之后的代码,其中父进程中fork会返回一个非零的数,而子进程中将返回零。
上面的代码完成和system(”date”)相同的功能。比起system单纯地调用外部命令,fork可以完成更加复杂的进程操作。
PERL中对SHELL命令的调用细节在PERL开发中,通常可以用system函数或
``操作符来执行系统命令,但注意对alias, bg, bind, break, builtin, cd, command,
compgen, complete, continue, declare, dirs, disown, echo, enable,
eval, exec, exit, export, fc, fg, getopts, hash, help, history,
jobs, kill, let, local, logout, popd, printf, pushd, pwd, read,
readonly, return, set, shift, shopt, source, suspend, test, times,
trap, type, typeset, ulimit, umask, unalias, unset,
wait等shell内部命令(即在文件系统中无执行文件的命令)这样直接执行会出错,错误是无法找到该文件或目录。可以在命令前加sh
–c来实现。而对cd、umask等SESSION型命令,应该用PERL的内部函数chdir、umask等来实现功能更可靠。补:如果用system调用后台程序,肯定是希望不影响前台的CGI程序响应
HTTP请求,这时候注意,Firefox可以立刻得到
system调用后的输出,IE不行,会等到system调用的后台程序执行完才得到之后的HTTP输出。其实只需要在system调用的后台程序里加
>/dev/null
2>&1把输出重定向就可以解决IE的响应问题了。
解析九大Perl目录操作函数用法
2010-07-15 13:50 jxncyjq csdn.net
你对Perl目录操作函数的概念是否熟悉,这里向大家简单介绍一下,Perl自带的函数远不及php多,但功能确实很强大,实现起来也只有几行代码。
AD:
本文和大家重点讨论一下Perl目录操作函数的概念,这里主要介绍一下九种Perl目录操作函数的用法,希望通过本文的学习你对Perl目录操作函数的概念有所了解。
Perl目录操作函数:
Perl自带的函数远不及php多,但功能确实很强大,实现起来也只有几行代码。
1、Perl目录操作函数之mkdir函数
调用语法:mkdir(dirname,permisions)
dirname:将要创建的目录名,可以为字符串或表达式、
permisions:八进制数,指定目录的访问权限、
目录的访问权限、其值和意义如下:
权限 值权限
4000运行时设置用户ID
2000运行时设置组ID
1000粘贴位
0400拥有者读权限
0200拥有者写权限
0100拥有者执行权限
0040组读权限
0020组写权限
0010组执行权限
0004所有人读权限
0002所有人写权限
0001所有人执行权限
2、Perl目录操作函数之chdir函数
调用语法:chdir(dirname)
3、Perl目录操作函数之opendir函数
调用语法:opendir(dirvar,dirname)
dirvar:目录句柄,与文件句柄类似
dirname:目录名,可为字符串或表达式
调用成功返回真,否则返回假
4、Perl目录操作函数之closedir函数
调用语法:closedir(mydir)
5、Perl目录操作函数之readdir函数
调用语法:readdir(mydir)
6、Perl目录操作函数之telldir函数
调用语法:location=telldir(mydir)
返回当前所在目录
7、Perl目录操作函数之seekdir函数
调用语法:seekdir(mydir,location)
location必须为telldir函数返回的值
8、Perl目录操作函数之rewinddir函数
调用语法:rewinddir(mydir)
9、Perl目录操作函数之rmdir函数
调用语法:rmdir(dirname)
程序代码:
#!/usr/bin/Perl
sublistdir{my@arr,$j=0;
for($i=0;$i<=$#_;$i++){
if(-d$_[$i]){
if(opendir($handle,$_[$i])){
while($dir=readdir($handle)){
if(!($dir=~m/^\.$/)and!($dir=~m/^(\.\.)$/)){
print"$dir";
if(-d$_[$i]."\\$dir"){
$arr[$j++]=$_[$i]."\\$dir";
print"\t[DIR]"
}
print"\n";
}
}
closedir($handle);
}
}
}
if($j>0){
listdir(@arr);
}
}
listdir"D:\\download";
问题1: 在perl中改变工作目录的方法,调用chdir
$directorylocation=`pwd`;
chdir $directorylocation;
上面的case是不会正确的,原因是因为从pwd中获取的字符需要进行处理:
$directorylocation=`pwd`;
chomp($directorylocation);
chdir $directorylocation;
Perl 中的正则表达式
正则表达式的三种形式
正则表达式中的常用模式
正则表达式的 8 大原则
正则表达式是 Perl 语言的一大特色,也是 Perl
程序中的一点难点,不过如果大家能够很好的掌握他,就可以轻易地用正则表达式来完成字符串处理的任务,当然在 CGI
程序设计中就更能得心应手了。下面我们列出一些正则表达式书写时的一些基本语法规则。
9.1 正则表达式的三种形式
首先我们应该知道 Perl 程序中,正则表达式有三种存在形式,他们分别是:
匹配:m// (还可以简写为
// ,略去 m)
替换:s///
转化:tr///
这三种形式一般都和 =~ 或 !~ 搭配使用(其中 "=~" 表示相匹配,在整条语句中读作 does,"!~"
表示不匹配,在整条语句中读作 doesn't),并在左侧有待处理的标量变量。如果没有该变量和 =~ !~ 操作符,则默认为处理 $_
变量中的内容。举例如下:
$str = "I love Perl";
$str =~ m/Perl/; # 表示如果在 $str 中发现 "Perl" 字符串,则返回 "1" 否则返回
"0"。
$str =~ s/Perl/BASH/; # 表示将变量 $str 中的 "Perl" 字符串替换为
"BASH",如果发生此替换则返回 "1",否则返回 "0"。
$str !~ tr/A-Z/a-z/; # 表示将变量 $str 中的所有大写字母转化为小写字母,如果转化发生了则返回
"0",否则返回 "1"。
另外还有:
foreach (@array) { s/a/b/; } # 此处每次循环将从 @array 数组中取出一个元素存放在
$_ 变量中,并对 $_ 进行替换处理。
while () { print if (m/error/);
} # 这一句稍微复杂一些,他将打印 FILE 文件中所有包含 error 字符串的行。
Perl 的正则表达式中如果出现 () ,则发生匹配或替换后 () 内的模式被 Perl 解释器自动依次赋给系统 $1, $2
...... 请看下面的例子:
$string = "I love perl";
$string =~ s/(love)//; # 此时 $1 =
"love",并且该替换的结果是将 $string 变为 "I
perl"
$string = "i love perl";
$string =~
s/(i)(.*)(perl)/$2/;
# 这里 $1 = "i",$2 = " love ",$3 = "perl",并且替换后 $string 变为
" love
"
替换操作
s///
还可以在末尾加上 e 或 g 参数,他们的含义分别为:
s///g
表示把待处理字符串中所有符合 的模式全部替换为
字符串,而不是只替换第一个出现的模式。
s///e
表示将把
部分当作一个运算符,这个参数用的不多。
比如下面的例子:
$string = "i:love:perl";
$string =~ s/:g; #此时 $string="i*love*perl";
$string =~ tr
找寻符合 * 这个字符,因为 *
在常规表达式中有它的特殊意思,所以要在这个特殊符号前加上 \ 符号,这样才会让这个特殊字符失效
/abc/i
找寻符合 abc 的字符串而且不考虑这些字符串的大小写
9.3 正则表达式的八大原则
如果在 Unix 中曾经使用过 sed、awk、grep 这些命令的话,相信对于 Perl
语言中的正则表达式(Regular Expression)不会感到陌生。Perl
语言由于有这个功能,所以对字符串的处理能力非常强。在Perl语言的程序中,经常可以看到正则表达式的运用,在 CGI
程序设计中也不例外。
正则表达式是初学 Perl 的难点所在,不过只要一旦掌握其语法,你就可以拥有几乎无限的模式匹配能力,而且 Perl
编程的大部分工作都是掌握常规表达式。下面给大家介绍几条正则表达式使用过程中的 8 大原则。
正则表达式在对付数据的战斗中可形成庞大的联盟——这常常是一场战争。我们要记住下面八条原则:
·
原则1:正则表达式有三种不同形式(匹配(m/ /),替换(s/ / /eg)和转换(tr/ /
/))。
·
原则2:正则表达式仅对标量进行匹配( $scalar =~ m/a/; 可以工作; @array =~ m/a/
将把@array作为标量对待,因此可能不会成功)。
·
原则3:正则表达式匹配一个给定模式的最早的可能匹配。缺省时,仅匹配或替换正则表达式一次( $a = 'string
string2'; $a =~ s/string/ /; 导致 $a = 'string 2')。
·
原则4:正则表达式能够处理双引号所能处理的任意和全部字符( $a =~ m/$varb/
在匹配前把varb扩展为变量;如果 $varb = 'a' $a = 'as',$a =~ s/$varb/ /; 等价于 $a =~
s/a/ /; ,执行结果使 $a = " s" )。
·
原则5:正则表达式在求值过程中产生两种情况:结果状态和反向引用: $a=~ m/pattern/ 表示 $a
中是否有子串 pattern 出现,$a =~ s/(word1)(word2)/$2$1/
则“调换”这两个单词。
·
原则6:正则表达式的核心能力在于通配符和多重匹配运算符以及它们如何操作。$a =~ m/\w+/
匹配一个或多个单词字符;$a =~ m/\d/" 匹配零个或多个数字。
·
原则7:如果欲匹配不止一个字符集合,Perl使用 "|" 来增加灵活性。如果输入 m/(cat|dog)/
则相当于“匹配字符串 cat 或者 dog。
·
原则8:Perl用
(?..) 语法给正则表达式提供扩展功能。(这一点请同学们课后看相关资料)
想要学习所有这些原则?我建议大家先从简单的开始,并且不断的尝试和实验。实际上如果学会了 $a =~ m/ERROR/
是在 $a 中查找子串ERROR,那么你就已经比在 C 这样的低层语言中得到了更大的处理能力。