jojo's blog--快乐忧伤都与你同在
为梦想而来,为自由而生。 性情若水,风起水兴,风息水止,故时而激荡,时又清平……
posts - 11,  comments - 30,  trackbacks - 0
定义:正则表达式是一种字符串模式,可用来和字符串进行匹配。匹配可能成功,也可能失败。许多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/      #会和moemole匹配,不会和Elmo匹配
/\bFred\b/   #会和Fred匹配,但FrederickalFred都不匹配
/\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@^/user/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 阅读(1003) 评论(0)  编辑  收藏 所属分类: Linux 技术相关

只有注册用户登录后才能发表评论。


网站导航:
 

<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用链接

留言簿(6)

随笔档案

文章分类

文章档案

新闻分类

新闻档案

相册

收藏夹

搜索

  •  

最新评论

阅读排行榜

评论排行榜