定义:正则表达式是一种字符串模式,可用来和字符串进行匹配。匹配可能成功,也可能失败。许多UNIX命令,包括grep, sed, awk, ed, vi, emacs都有正则表达式的功能。Perl也有这种功能。Python也具有这种功能。
简单示例:
例如:
grep abd readme.file > result.txt
则Perl中,写成
if(/abc/)
{
print $_;
}
在Perl中,正则表达式用斜线标记,以代表斜线之间的内容是个正则表达式。当表达式北斜线包围时,Perl会拿$_和它作比较,以判断条件的真假。
while(<>) {
if (/abc/) {
print $_;
}
}
这个程序片断能读入某文件的所有内容,并进行匹配。
grep “ab*c” readme.file > result
while( <> )
{
if (/ab*c/) {
print $_;
}
}
以上程序片断表示以a开头,后面跟0个以上的b,最后以c结尾。
替代运算符以s字母开头,跟正则表达式,再跟替代的运算符号。
s/ab*c/def/
变量是$_会跟正则表达式(ab*c)做比较。进行匹配。
类型:一个“正则表达式”就是一种类型pattern。分为单字符类型和多字符类型。
单字符类型:单字符类型是最常见和最常用的类型。如a。单字符类型”.”能跟除换行符号(\n)的任何字符匹配。如
/a./
会和任何长度为二,且开头是a的字符串匹配。除了”a\n”外。
字符类:(character class),写法是左右两个中括号([]),内放字符。即字符串对应此类型的地方,若出现唯一一个符合括号中列出的字符,就算符合。
/[abcde]/
/[aeiouAEIOU]/
若在中括号中放[或者],则需要在前面加反斜杠。如果想表示一段范围,则可以用破折号(dash-)连接。想表示破折号,则前面也必须加反斜杠。
[0123456789]
[0-9]
[0-9\-]
[a-zA-Z]
也可以用“反例”表示字符类别,只要在原来的写法前加上“^”即可。此种类型的意思是任何不在此类别内的单一字符才算上匹配。
[^0-9]
[^aeiouAEIOU]
[^\^]
预定义的字符类别
字符
|
类别
|
反例
|
反例类别
|
\d
|
[0-9]
|
\D
|
[^0-9]
|
\w
|
[a-zA-Z]
|
\W
|
[^a-zA-Z]
|
\s
|
[\r\t\n\f]
|
\S
|
[^\r\t\n\f]
|
[\da-fA-F] #十六进制数字
类型组合:grouping pattern就是将正则表达式组合起来用。
系列:sequence, 如”abc”
重复符号:multiplier,如星号(*)表示出现零次以上;加号(+)则表示出现一次以上;问号(?)则表示出现零次或一次。
/fo+ba?r/
以上的类型都是贪婪型的greedy。
$_ = “fred xxxxxxxxx barney”;
s/x+/boom/
一般重复符号:(general multiplier),写法是一对大括号中放一个或两个数字,如/x{5, 10}/,表示x出现5到10次;/x{5,}/表示出现5次以上;/x{5}/表示刚好5个x;/x{0,5}/意思就是”0到5个”
正则表达式如出现两个重复符号,必须遵循“最左边最贪心”(leftmost is greediest)的规则。
$_ = “a xxx c xxxxxxxxxx c xxx d”;
/a.*c.*d/;
以这个例子,第一个“.”就会和第二个c之前所有的字符符合。可以在重复符号后面加上问号,让它变得“不贪心”(nongreedy)。
$_=”a xxx c xxxxxx c xxx d”;
/a.*c?.*d/
把字符串和正则表达式再该一下:
$_=”a xxx ce xxxxxxx ci xxx d”;
/a.*ce.*d/
这个例子中.*如果匹配到第二个c,则e没有办法匹配。故Perl会重试,降低了效率。实际上只要加个”?”就能让Perl少做很多事。
把括号当记忆空间:另外一个组合符号,是前后包围任何类型的括号对(parentheses pair)。括号不会改变类型匹配的情形,不过可以把匹配的部分记录下来,以后参考。调用记住部分,写法是在反斜线后面加上数字。
/fred(.)barney\1/;
会和fredxbarneyx匹配,不会和fredxbarneyy匹配。但是/fred.barney./和两个字符串都匹配。
其中\1代表正则表达式中,第一个用括号括起来的部分。依次有\2, \3…
/a(.)b(.)c\2d\1/;
可以在括号中放入一个以上的字符。如/a(.*)b\1c/;
选项符号:还有一种组合符号称为选项符号(alternation),如“a|b|c”。选项可以不只一个字符,如/song|blue/。
定位类型:anchor pattern定位类型有好几种。定位类型\,表示目标字符串的这个地方必须是文字边界(word boundary)。所谓“文字边界”就是指符合\w或\W的字符,二个中间的位置;或者界于任何符合\w的字符,与字符串开头(或结尾)中间的位置。
/fred\b/; #会和fred匹配,不会和Frederick匹配
/\bmo/; #会和moe和mole匹配,不会和Elmo匹配
/\bFred\b/; #会和Fred匹配,但Frederick或alFred都不匹配
/\b\+\b/; #会和x+y匹配,不会和++或+匹配
另一个定位类型\B所在之处就不一定是文字边界,如
/\bFred\B/; #会和Frederich匹配,但Fred Flintstone不匹配
还有两种类型,代表字符串的开头或结尾的前一个字符。“^”会和字符串的“开头”匹配。^a会匹配以a开头的字符串,不过a^会和”a”和”
^”这两个字符串匹配。即”^”失去了特别的意义
。如果想表示字符串开头是有个^号,则用\^即可。另外一个定位类型是”$”,不过表示字符串结尾。c$表示最后出现的字符是c的那个字符串。表示$这个
字符,用\$表示。
优先级:
名称
|
表示法
|
括号(parentheses)
|
() (?:)
|
重复运算符(multiplier)
|
? + * {m, n} ?? +? *? {m, n}?
|
序列和定位符号(sequence and anchoring)
|
abc^$\A\Z(?=) (?!)
|
选项符号(alternation)
|
|
|
abc* #会和ab, abc, abcc, abccc, abcccc匹配
(abc)*
^x|y
^(x|y)
a|bc|d
(a|b)(c|d)
(song|blue)bird
=~运算符:如果拿来匹配的字符串,不放在$_变量,则可以用”=~”运算符来解决:可把正则表达式放在运算符右侧,左侧则是想比较的字符串。即把正则表达式的默认目标转向运算符的左边运算单元。
$a = “hello world!”;
$a =~ /^he/;
$a=~/(.)\1/;
if($a=~/(,)\1/)
任何能传回标量字符串值的语句,都可以当作=~运算符的左边单元。如,如
print “any last request?”;
if( =~ /^[yY]/) {
print “And just what might that request be”;
print “Sorry, I’m unable to do that.\n”
}
忽略大小写:grep有-I这个旗标,意思是忽略大小写;在Perl中提供了类似的方法:在正则表达式第二个斜线之后写上I即可。如/somepattern/i。
print “any last request?”;
if ( =~ /^y/i)
{
}
指定界限符号:正则表达式前后用斜线包起来,斜线叫分界符号(delimiter),如果想在正则表达式表示斜线这个“字符”,在前面加反斜线。
$path =
if($path =~ /^\/usr\/etc/) {
}
Perl允许设计者自行指定分界符合。可用任何-个非字母、非数字、非空白的字符为分界符号,方法是在第一次使用之前写”m”。
/^\/usr\/etc/
m#^/usr/etc#
内插变量:正则表达式也可以内插变量。
$what = “bird”
$sentence = “Every good bird does fly.”;
if($sentence =~ /\b$what\b/)
{
print “The sentence contains the word $what\n”;
}
下面的例子稍微复杂一些:
$sentence = “Every good bird does fly.”;
print “What should I look for?”;
$what = ;
chomp($what);
if($sentence =~ /$what/)
{
print “I saw $what in $sentence.\n”;
}
else
{
print “nope… didn’t find it.\n”;
}
特别的只读变量:匹配成功后,名为$1, $2, $3…的这些变量,它们的值被分别设为\1,\2,\3…之值。
$_ = “this is a test”;
/(\w+)W+(\w+)/;#和头两个文字匹配;现在$1是”this”,$2是”is”。
也可以在列表环境下,一次取得所有匹配的片断。
$_=”this is a test.”;
($first, $second) = /(\w+)W+(\w+)/;
其他预定义的只读变量包括:”$&”,代表字符串中匹配正则表达式的部分;”$`”代表匹配处之前的部分;”$’”代表匹配处之后的部分。
$_=”this is a sample string.”;
/sa.*le/; #和sample匹配。s`是”this is a “,$&是”sample”,$’是”string”
替代运算符:s/old-regex/new-string/这样的用法是最简单的一种替代运算符。如果想让替代运算符在每个匹配的地方取代,而非仅作用在第一个匹配处,在运算符加g.
$_=”foot fool buffoon”;
s/foo/bar/g;
替代运算符也可以内插变量,像这样:
$_=”hello, world”;
$new = “goodbye”;
s/hello/$new/;
可以在替代运算符里用字符类型,就不会和固定的字符匹配了:
$_=”this is a test”;
s/(\w+) /<$1>/g; #$_现在是
替代运算符可以加上i,代表忽略大小写,如果已经有g了,则i可以出现在g前后。斜线还可以用其他符号代替。s#fred#barney#;替代运算符也可以用=~改变作用的目标。
split和join函数:正则表达式可以把字符串分成许多字段。split函数可以这样做。而join函数则可以把这些片断组合起来。
split函数有两个参数,分别是正则表达式和字符串,它会寻找字符串中匹配正则表达式的部分,其他不匹配的部分会依序用列表值方式传回。
$line= “merlyn::118:10:Randal:/home/merlyn:/urs/bin/perl “;
@fields = split(/:/, $line);
如果要匹配一个以上的:则用:
@fields = split(/:+, $line);
变量$_是split函数的第二个参数的默认值:
$_=”some string”;
@words =split(/ /);
由于参数字符串内没有连续的空白字符,结果会是空字符串。理想的写法是/ +/, /\s+/和”一个以上“的空白字符匹配。这是第一个参数的默认值。
@words = split;用空白字符分割$_。
$line=”merlyn::118:10:Randa;:/home/merlyn:”);
($name,$password,$uid,$gid,$gcos,$home,$shell)=split(/:/,$line);
join函数跟split函数对应,该函数用第一个参数字符串当作”胶”,把第二个参数里面的值一个个“粘“起来。
$bigstring=join($glue,@list);
posted on 2009-02-03 15:19
Blog of JoJo 阅读(1014)
评论(0) 编辑 收藏 所属分类:
Linux 技术相关