Perl Regular Expressions (Perl 正则表达式)
我现在主要用PHP来写代码,当用到Regular Expressions的时候,就想到了我以前常用到的Perl Regular Expressions。虽然二者是使用方法所不同的,但是字符串匹配的规则是大体相通的,而且PHP兼容Perl的匹配规则(Pattern)。因此,我想先把Perl的正则表达式回顾总结一下。(参考:Steve Litt's Perls of Wisdom)
正则表达式的作用:
1. 判断字符串是否和一个特定字符或字符串匹配
- $string =~ m/sought_text/; #如果这个表达式成立,那么$string里就含有特定字符'sought_text'。
2. 选择字符串里的特定部分
- $string =~ m/whatever1(sought_text)whatever2/;
- $soughtText = $1; #如果上面的表达式成立,那么$1就是'whatever1'和'whatever2'之间的那部分
3.字符串替换/翻译
- $string =~ tr/originaltext/newtext/; 把字符串里'orignialtext'用'newtext'来代替
常用通配符和重复方法:
. 匹配任意字符 (除了换行符"\n")^ 表示字符开始的空字符
$ 表示字符结束的空字符
\w 匹配任意(文字和数字)字母和下滑线
\W 匹配非任意(文字和数字)字母和下滑线的字符
\s 匹配空格符
\S 匹配非空格符
\d 匹配数字
\D 匹配非数字
\t 匹配'tab'键值
\n 匹配换行符
\r 品牌回车键
* 匹配0次或者多次
+ 匹配一次或者多次
? 匹配0次或者一次
{n} 刚好匹配n次
{n,} 匹配n次以上,包含n
{n,m} 匹配n次以上,但是不超过m次
例子:
$string =~ m/\s*rem/i;#如果以上表达式成立,那么$string可以是以任意个空字符开始然后紧跟着非空字符可以为#'rem'或者'REM'(不分大小写)$string =~ m/^\S{1,8}\.\S{0,3}$/;#以上表达式用来匹配1到8个的非空字符紧跟着一个'.',然后再紧跟着0-3个的非空字符。#比如说'abcd.', 'a.34s',但是不匹配'.12dg','.123',等等。
匹配组, group()
如果我们想对一组字符进行匹配,我们可以用()。
例子:
if($string =~ m/(A|E|I|O|U|Y|a|e|i|o|u|y)/){print "String contains a vowel!\n"}#以上判断字符串是否包含元音if($string =~ m/^(Clinton|Bush|Reagan)/i){print "$string\n"};#以上判断字符串是否已Clinton,Bush,Reagan中一个开头,不分大小写
匹配单一字符,character classes []
如果我们想匹配一组字符的中一个,我们可以用[]。
例子:
if($string =~ /[AEIOUYaeiouy]/){print "String contains a vowel!\n"}#这等同于上面的提到的组匹配,但是你会发现用'[]'要简介许多if($string =~ m/(A|E|I|O|U|Y|a|e|i|o|u|y)/){print "String contains a vowel!\n"}if($string =~ /[^AEIOUYaeiouy]/){print "字符串没有包含任何元音字母"}#注意:上面这个例子中'^'不是表示起始空字符,而是表示'非'if($string =~ m/^[A-E]/){print "字符串是以A-E中的任何一个字母开头的\n"}#注意:上面这个例子中'^'表示起始空字符
字符串替代 s
例子:
$string =~ s/少儿上网/61dh\.com/;#把字符串里的'少儿上网'用61dh.com来代替。注意:因为'.'表示任意字符,所以当我想表示'.'这个特殊字符时,可以用'\.'来表示。
字符串翻译 tr
和字符串替代比较相似,但是也有它独特的地方:把一组字符串的字符一一对应的替换。
例子:
$string =~ tr/[a-z]/[A-Z]/;#把小写字母转换成大写字母$string =~ tr/[六,一,导,航]/[6,1,d,h]/;#把'六一导航'翻译成'61dh'
贪婪匹配和不贪婪匹配
Perl的正则表达式通常是贪婪匹配的,也就是说它尽量匹配更多的字符。这么说比较抽象,让我们看例子:
my($text) = "mississippi";$text =~ m/(i.*s)/;print $1 . "\n";#'*'表示匹配0个或者多个,因为Perl比较贪心,所以匹配结果是’ississ'$text =~ m/(i.?s)/;print $1 . "\n";#'*'表示匹配0个或者一个,同样Perl尽量去匹配多,所以结果是'iss'
如果想找到字符串里第一次出现'i'和's'的情况。也就是所谓的不贪婪匹配。我们可以同时使用'*'和'?'。
例子:
my($text) = "mississippi";$text =~ m/(i.*?s)/;print $1 . "\n";#这下结果为'is'
补充(11/6/08):需要匹配多行的字符串,可以使用“smi”后缀修饰。例如:
$a = '<{LIST(10011002,10,0,0)}><tr><td width="100"> </td><td> </td><tr><{/LIST}> ';if ($a =~ /<{[^}]+}\>(.+)\<{[^}]+}>/smi){print "yes";}
标签: Perl



4 条评论:
请问正则表达式前面的m或者tr表示的是什么?
作者
freefrank, 时间
2008年10月6日 下午1:20
1. m是match,也就是匹配的意思
例子:
my($text) = "mississippi";
$text =~ m/(i.*s)/;
print $1 . "\n";
#意思是在$text字符串里,把和(i.*s)匹配的部分取出。
2. tr是translate, 也就是翻译的意思
例子:
my $string = "abc";
$string =~ tr/[a-z]/[A-Z]/;
#意思是把$string里的小写字母转换成大写字母,得到ABC。
作者
Adam, 时间
2008年10月7日 上午11:59
我对用英文写perl script 很熟。但我没弄清楚如何用Perl来处理中文文件。比如我有一份中文text文件,我如何写一个Perl script来parse它。
从您的例子
$string =~ s/少儿上网/61dh\.com/;
似乎可以将中文字encode进去。
不知您是否可以提供一个完整的script例子?
谢谢!
Fred
作者
Anonymous, 时间
2008年12月28日 下午2:30
Fred:
Perl 用的是UTF-8。如果你的终端用的是UTF-8字符集,你可以直接使用中文。
如果你用的是GB2312, 你可以先进行编码转换,
例如:
$a 是GB2312 编码的字符串,
$b = decode("GBK", $a); 或者 $b = encode("UTF-8", $a);
这样得到的$b就是UTF-8编码,然后再对$b进行处理了
作者
Adam, 时间
2008年12月29日 下午9:59
发表评论
指向此帖子的链接: