Download presentation
Presentation is loading. Please wait.
1
Perl 语言 1
2
第八章用正则表达式进行匹配 1 用m//进行匹配 ※ 2 模式匹配修饰符 △ 3 锚位 △ 4 捕获变量 2
3
现在你将学习怎样在Perl 中使用正则表达式。
3
4
8.1使用m//匹配 我们曾经将模式放在一对正斜线(//)里面,如/fred/。 实际上是m//(模式匹配)的一种简写。同qw//。
也可以使用m(fred), m<fred>, m{fred}, m[fred],或者m,fred,, m!fred!, m^fred^。 如果使用//,可以省略m 4
5
8.1使用m//匹配 建议:使用模式中不会出现的字符作为分隔符。 /http:\/\// #匹配http://。
5
6
8.2 模式匹配修饰符 修饰符(modifier),通常叫做标记(flag),可以后缀在正则表达式后面来改变其默认的行为。
要创建一个大小写无关的模式,如匹配FRED 时,也能匹配上fred, Fred,可以使用修饰符/i: print “Would you like to play a game?”; chomp($_ = <STDIN>); if(/yes/i) { #大小写无关 print “In that case, I recommend that you go bowling.\n”; } 6
7
8.2 模式匹配修饰符 2.匹配任何字符:/s 点(.)不匹配换行符,如果希望点(.)能匹配任意字符(包括换行符),可以使用/s 修饰符。
此时(.)相当于 [\d\D] $_ = “I saw Barney\ndown at the bowing alley\nwith Fred\nlast night.\n”; if(/Barney.*Fred/s){ print “That string mentions Fred after Barney!\n”; } 7
8
8.2 模式匹配修饰符 3.加入空白符:/x 允许你在模式中加入任何数量的空白,以方便阅读:
/-?\d+\.?\d*/ #这是什么含义? / -? \d+ \.? \d* /x #要好些 由于/x 允许模式中使用空白,原来模式中的空格,制表符等将被忽略。可以使用\s(\s*或\s+)。 $_=“4 4” / \d \d/x #错误 / \d \s+ \d/x #成功 8
9
8.2 模式匹配修饰符 Perl 中,注释可以被作为空白,因此使用/x,可以在模式中加上注释: / -? #可选的负号
-? #可选的负号 \d #小数点前一个或多个十进制数字 \.? #可选的小数点 \d* #小数点后一些可选的十进制数字 /x #模式结束 9
10
8.2 模式匹配修饰符 如果需要匹配井号,可以使用\#或[#] / [0-9]+ #必须出现一个或多个数字 [#]+ #井号字符本身
[0-9] #必须出现一个或多个数字 [#] #井号字符本身 /x #模式结束 注释部分不能出现定界符号,否则被视为模式终点。 / -? #有减号/没有减号 错误,使用了定界符 [0-9] #必须出现一个或多个数字 [#] #井号字符本身 /x #模式结束 10
11
8.2 模式匹配修饰符 组合选项修饰符 在一个模式中可以使用不止一个修饰符,可以一个接着一个写在模式末尾。其顺序是不重要的:
if(/barney.*fred/is){ # /i 和/s print “That string mentions Fred after Barney!\n”; } if (m{ barney #小伙子barney .* #可以包含任何字符,包括换行符 fred #小伙子fred }six) { #修饰符包括包括/s, /i, /x print “That string mentions Fred after Barney!\n”; } 11
12
8.3 锚位 默认情况下,如果模式在字符串开头没能匹配上,它会顺着字符串下去,直到匹配上为止。
锚定(anchors):要求模式在特定的位置进行匹配 \A锚位匹配字符串的绝对开头,如果在开始位置不匹配,则不会顺移到下一个位置。 m(\Ahttps?://)i #判断字符串是否以https开头 12
13
8.3 锚位 \z锚位匹配字符串的绝对末尾 \Z锚位匹配字符串的末尾(允许后面出现换行符)
m(\.png\z)i #判断字符串是否以.png结尾 \Z锚位匹配字符串的末尾(允许后面出现换行符) 同时使用行首锚位和行末锚位,确保模式能匹配给定字符串的全部。 /\A\s*\Z/,匹配一个空行,允许出现制表符,空格等 13
14
8.3 锚位 Perl5之前的版本,使用^,$来锚位字符串开头和结尾,使用方法与\A,\z相同 不同之处:
^,$可以使用/m修饰符,来匹配多行字符串的开头或结尾 $_ ='this is a wilma line barney is on another line but this ends in fred and a final dino line'; if( m/fred$/m ){ print “It matched!\n"; } 14
15
8.3 锚位 单词锚位 锚位不仅针对字符串的首尾。\b,单词边界锚位/\bfred\b/可以匹配fred,
不能匹配frederick,alfred, manfredmann 称之为“整词匹配” 15
16
8.3 锚位 单词不是一般的英文单词, 是由一组\w字符构成的字符集。 (字母,数字,下划线组成的字符串) 16
17
8.3 锚位 单词边界锚位是非常有用的: 如果不希望cat 匹配上delicatessen,可以使用/\bcat\b/
/\bhunt/ 能够匹配hunt, hunting,但不会匹配shunt /stone\b/匹配sandstone, 不匹配capstones。 非词界锚定为\B。任何非\b 匹配的点上进行匹配。 /\bsearch\B/将匹配searches, searching, searched, 但不能匹配search,或者researching。 17
18
绑定操作符 默认对$_匹配, 绑定操作符( =~ 将右边的模式在左边的字符串上进行匹配,而非匹配$_ 。
绑定操作符( =~ 将右边的模式在左边的字符串上进行匹配,而非匹配$_ 。 my $some_other = “I dream of betty rubble.”; if($some_other =~ /\brub/){ print “Aye, there’s the rub.\n”; } my $likes_perl = <STDIN> =~ /\byes\b/i; #绑定操作符的优先级特别高,先进行匹配,再将匹配的结果赋值給变量。 18
19
模式中的内插 正则表达式可以被内插,如同双引号字符串一样 my $what = “larry”; while(<>){
if(/^($what)/){ #在字符串前面进行匹配 print “We saw $what in beginning of $_;”; } 19
20
8.4 捕获变量 圆括号出现的地方一般都会触发正则表达式引擎捕获匹配的字符串。捕获组会把匹配圆括号中模式的字符串保存到相应的地方。捕获组中包含的是原始字符串的内容,不是模式本身。 可以使用反向引用或相应的捕获变量取得这些内容 捕获变量$1, $2 存储第一个,第二个捕获组中的字符串 \1 与 $1 20
21
8.4 捕获变量 捕获变量是组成正则表达式强大功能的重要部分,它允许取出相应的字符串; 如果字符串不符合模式,则捕获变量为空
$_ = “Hello there, neighbor”; if(/\s([a-zA-Z]+),/){ #空格和逗号之间的词 print “the word was $1\n”; #the word was there } if(/(\S+) (\S+), (\S+)/){ print “words were $1 $2 $3”; #words were Hello there neighbor 21
22
捕获变量的存续期 这些捕获变量的值会保持不变,直到下一个模式成功匹配为止 如果需要存储捕获变量,则应将其赋值給其他变量
my $wilma = ‘123’; $wilma =~ /(\d+)/; #成功匹配,$1存储123 $wilma =~ /([a-zA-Z]+)/; #不匹配,$1仍然存储123 print “Wilma’s word was $1… or was it?\n” #打印123 my $wilma_word = $1 22
23
不捕获模式 圆括号会捕获部分的匹配字符串到捕获变量中,但如果我们只想让圆括号执行分组的功能,则需使用“不捕获模式”
不捕获圆括号(?:),仅仅为了分组而存在 if (/(?:bronto)?saurus(steak|burger)/){ print “Fred wants a $1\n”; } 23
24
命名捕获 要维护$1, $2与圆括号之间的对应关系,比较困难。 my $names = ‘Fred or Barney’;
if ($names =~ /(\w+) and (\w+)/){ print “I saw $1 and $2”; #不成功 } if ($names =~ /(\w+) (and|or) (\w+)/){ print “I saw $1 and $2”; #$2得到的是择一匹配的内容,or if ($names =~ /(?<name1>\w+) (?:and|or) (?<name2>\w+)/){ print “I saw $+{name1} and $+{name2}”; 24
25
命名捕获 这是一种对捕获变量直接命名的方法 捕获的内容会存在特殊哈希%+中,键是捕获时的特殊标签(命名),value是捕获的字符串
(?<LABEL>PATTERN),LABEL可以自行命名, 访问变量$+{LABEL} my $names = ‘Fred or Barney’; if ($names =~ /(?<name1>\w+) (?:and|or) (?<name2>\w+)/){ print “I saw $+{name1} and $+{name2}”; } 25
26
命名捕获 使用捕获标签后,反向引用也随之变化,原来的\1或\g{1}写出\g{LABEL}
my $names = ‘Fred Flintstone and Wilma Flintstone’; if ($names =~ /(?<last_name>\w+) and \w+ \g{last_name}/){ print “I saw $+{last_name} ”; } 26
27
自动捕获变量 三个变量名为: $&, $`, $’。 $&: 存储整个模式所匹配的字符串 $`:存储匹配区段之前的字符串内容
$’:存储匹配区段之后的字符串内容 if(“Hello there, neigbor”=~ /\s(\w+),/){ print “That actually matched ($&) ($`) ($’) ($1).\n”; #( there,) (Hello) ( neigbor) (there) } 27
28
通用量词 三个数量词:*, +, ?。 如果表示其他数量使用花括号({})
模式/a{5,15}/将匹配a5至15次 。a 出现3 次,次数太少,不能匹配;出现5 次,匹配;出现10 次,匹配上。如果出现20 次,仍将匹配上,前15 个将匹配上。 /(fred){3,}/,表示匹配fred3次以上 /\w{8}/,表示匹配8个字符的单词 星号(*)等同于{0,},加号(+)等同于{1,},问号(?)则等同于{0,1} 28
29
优先级 1.最高等级是圆括号(),分组和捕获
2.第二级是数量词。星号(*), 加号(+),问号(?)以及由花括号表示的数量词,如{5,15}, {3, }, {5}等 3.第三级的是锚定和序列(sequence)。锚定包括(^) ($)(\A)(\z)(\Z)(\b)(\B)。序列abc 4.优先级最低的是择一控制符(|) 5. 原子(atoms),单独字符,反向引用,字符集 29
30
本章小结 掌握:模式匹配修饰符;锚位;捕获变量;模式中的内插 熟悉:用m//匹配,绑定操作符,通用量词,优先级 了解:测试程序 30
31
Thank You ! 31
Similar presentations