SOURCE HTML: http://socvista.com/bbs/redirect.php?fid=71&tid=922&goto=nextnewset
08:35
-- 用m//来实现匹配
我们前面提到的 // 其实就是 m// 的缩略方法,因为PERL使用者倾向于尽量节省书写。
另外m后面的分隔符可以使用任意的非数字和字母的符号,比如 m()、m{}、m,,、等等都是可以的。
-- 尽量使用正则表达式中没有出现的字符作为分隔符
比如要匹配 http://。两种方法:
1. m%http://%
2. m/http:\/\//
你可以看到第二种方法为了避免混淆表达式和分割符,使用了转义字符,降低了可读性。
-- 选项
选项符号加在正则表达式最后一个分隔符的后面,作用是改变表达式的默认行为。
/i:不区分大小写
/yes/i
/s:默认情况下.点符号不能匹配换行符,这个选项的作用是令点符号包含换行符。
/barney.*fred/s
/x:为了方便阅读需要在正则表达式中插入无实际意义的空格,这个选项就是表示将忽略这些为了阅读方便而使用的空格。当然真正的有意义的空格要用转义符来表示。不然会被忽略。
/-?\d+\.?\d*/ ====> / -? \d+ \.? \d*/x
还有一些其他的option,他们可以单独使用,也可以组合在一起使用,比如 //six
09:02 Anchor
-- Anchor 定位
/^fred/:^符号匹配首字母是fred的字符串
/fred$/:$符号匹配尾字母是fred的字符串
-- 匹配整个单词
/\bfred\b/:\b\b组合符号匹配整个单词,而不是单词中的一个部分。
-- 匹配单词的一部分
/\bsearch\B/:\b\B组合符号匹配单词的起始部分但是结束部分必须不匹配。比如searching或者searches之类。
09:08 binding operator
-- =~ 符号
默认情况下,我们使用m//或者//执行匹配时,是对$_进行的,因此常常省略。
但是有时候对其他变量执行匹配时就必须显示声明。比如,
if ($sth =~ /\byes\b/) {}
这里的 =~可以读作“匹配”。返回值是布尔型的。
另外 =~符号的运算优先级较高。所以写成下面这种形式也不会有错。
my $likes_perl = <STDIN> =~ /\byes\b/i;
09:38 匹配变量与记忆内存
-- match variable & memory
在匹配表达式中使用()的时候,不但能将模式组合起来,另外一个作用是提示perl将括号内的匹配结果用内存记忆起来。一般第一个括号对应的内存变量为
$1,第2个括号对应$2,以此类推。有时候及时匹配上了,结果也可能为空,特别是用*符号匹配时,0个也算是匹配,因此结果可能为空。
-- 变量如何被维持与修改
如果下一次匹配成功,则变量被更新。
如果下一次匹配失败,则变量被保持。
因此为了逻辑正确,必须确认匹配是否成功,否则极有可能使用了上次的结果,那是无效的。下面这样比较好。
if ($wilma =~ /(\w+)/) { # 先判断是否匹配成功
#some operation.
}
如果需要长期保存,则应当将匹配变量复制到普通变量中。比如,
my $wilma_word = $1;
-- automatic match variable (不重要)
这时系统内置的匹配变量和记忆内存,有三个变量。
$`:保存被匹配字符串匹配部分以前的内容。即//部分之前的内容。
$&:保存//内部所有匹配的内容,而$1只是保存()内部的内容,前者更多字符。
$':保存被匹配字符串匹配部分以后的内容。即//部分之后的内容。
如果使用这3个变量之一,程序的速度就会有所下降,虽然不是很大。
因此perl程序员一般还是通过修改()内的模式来获取$1变通实现。
12:46 通用的quantifier
-- 指定型quantifier
/(kobe){5,15}/ :匹配kobe连续出现5到15次的情况
/(kobe){5,}/ :匹配kobe连续出现5次以上的情况,没有上限
/(kobe){5}/ :匹配kobe连续出现5次的情况
事实上*?+也可以用这种方式表示出来。
12:53 优先级 precedence
第一级:括号
第二级:quantifiers。包括*+?和{lower,upper}
第三级:anchors 和 sequences。包括/^something/、/something$/、\b、\B
第四级:alternation:|
然后是原子符号,比如单个字符,字符分类[],和\转义字符。
12:56 模式验证程序
写完的正则表达式(模式)是否正常工作,我们需要有专门的程序来验证。这个功能对程序员非常有用。下面是一个实例。
#!/usr/bin/perl
while (<>) {
chomp;
if (/YOUR_PATTERN_GOES_HERE/) {
print "Matched: |$`<$&>$'| \n"; #也就是打印匹配出来的结果 |before <match> after|。和原数据比较即可知对错。
} else {
print "No match: |$_| \n";
}
}
13:23 (Aug.21) 当m//被使用在list 环境中时
== 用m//来输出一个list
在匹配表达式外面加上括号,这样在每次匹配时就会返回一个memory 变量,这些变量一起存入array。比如
my $text = "kobe dropped a 5 ton granite block";
my @word = ( $text =~ /([a-z]+)/ig ); # 返回的list为 "kobe" "dropped" "a" "ton" "granite" "block"。注意5被丢掉了。
== 用m//来输出一个hash表
my %last_name = ( $data =~ /(\w+)\s+(\w+)/g );