Perl语言入门笔记 第八章 用正则表达式进行匹配
#用正则表达式进行匹配 =pod m// = // = m%%,m||,m<>,m{},m(),匹配的时候根据需要写自己的定界符,像qw省略双引号定界符一样 模式匹配修饰符: 跟在定界符后面的,//x,x就是模式匹配修饰符 i 忽略大小写 s 匹配任意字符 if(/Barney.*Fred/s){}#s会把//里面的.全部替换为[\d\D],这是需要再让.匹配除\n以外的字符时,需要把.换成[^\n]或[\N] x 忽略空白,如/-?[0-9]+ \.? [0-9]* /x,这其中的空格被无视,加入需要的话可以再空格前面加上\,或着空格以\s*或\s+代替 组合选项修饰符: if(/barney.*fred/is){ } if(m{barney.*fred}six) {} 选择一种字符解释方式: /\w+/a #仅仅是A-Z、a-z、0-9、_这些字符 /\w+/u #任何Unicode当中定义为单词的字符 /\w+/l #类同于ACSII的版本,但单词字符的定义取决于本地化设定 #所以如果设定为Latin-9的话 其他选项: 锚位:perl5 \A: 匹配字符串的绝对开头 m{\Ahttps?://}i #判断字符串是否以https开头 \z: 匹配字符串的绝对末尾,\z后面再没其它东西 m{\.png\z}i #匹配以.png结尾的字符串 \Z: 行末锚位,它允许后面出现换行符 while(<STDIN>) { print if /\.png\Z/ }; /\A\s*\Z/:匹配一个空行 锚位:perl4 ^:脱字符开头锚位 $:结尾锚位 ->行末 匹配多行行末是fred的字串 /fred$/m 匹配单行最好用,\A,\z 单词锚位: \b: 只匹配以\w开头或结尾,只匹配字符[0-9a-zA-Z] /\bhunt/:匹配hunt hunting hunter,而不匹配shunt /stone\b/:匹配standstone flintstone但不包括capstones \B: 非单词边界锚位是\B,它能匹配所有\B不能匹配的位置 /\bsearch\B/会匹配searches、searching与searched,但不匹配search或researching #####没看懂啥意识,和\b有啥区别 绑定操作符=~: 默认情况下模式匹配的操作对象时$_,绑定操作符告诉perl,拿右边的模式来匹配左边的字符串,而不是匹配$_ 如:if($some_other =~ /\brub/) 快消类型:my $likes_perl = (<STDIN> =~ /\byes\b/i);#判断输入的数据中是否有yes子串,有的话,$likes_perl为1,否则为0 模式的内插: 即可插入变量,当做查找的参数 while(<>) { if(/\A($what)/) { print "We saw $what in beginning of $_"; } } my $what = shift @ARGV; 如果第一个命令行参数是fred|barney,则模式会变成/\A(fred|barney)/,也就是会在每行的开头寻找fred或barney。 捕获变量: 圆括号出现的地方一般都会触发正则表达式引擎捕获匹配到的字符串,捕获组会把匹配圆括号中模式的字符串保存到相应的位置,如果不止一个括号,就不止一个捕获组。每个捕获组包含的都是原始字符串中的内容,而不是模式本身。我们可以通过反向引用取得这些捕获内容,但也可以再匹配操作结束后立即通过相应的捕获变量取得这些内容。 因为有了捕获变量,我们才得拥有提取字符串中某些特定部分的能力。 if(/\s(\[a-zA-Z]+),/) #$1 if(/(\S+) (\S+) (\S+)/) #$1, $2, $3 捕获变量的存续期: 保存到下次匹配成功为止,再匹配成功则会将上次匹配的结果给覆盖掉。 如果想在数行之外使用捕获变量的话,最好将$1...赋给一个变量,这样也能增加程序的可读性,如my $wilma_word = $1; 不捕获模式:?: if(/(?:bronto)?saurus(steak|burger))#?:告诉bronto的圆括号只是为了分组才存在的。那么存在$1中的就是第二个括号里的steak|burger 命名捕获: if($name =~ m/(\w+)(and|or)(\w+))#现在能匹配了 my $name = 'fred or Barray'; if($names =~ m/(?<name>\w+)(?:and|or) (?<mame2>)\w+/) print "I saw $+{name1} and $+{name2}"; my $name = "Fred Filnstone and wilma filntstone"; if($names =~ m/(?<last_name>\w+/) and \w+ \g{lat_name}/) { say "I saw $+{last_name}"}; 自动捕获变量: $&, $`, $' if("Hello there, neighbor" =~ /\s(\W+),/) { print "That actually matched '$&'.\n"}; 匹配到的结果放到$&里,匹配区段之前的内容会存到$`里,而匹配区段之后的内容则会存到$'里,将三者依次连接起来,就一定会得到原来的字符串。 一旦使用了某个自动捕获变量,其他正则表达式的运行速度会变慢。 use 5.010; if("HEllo there, neighbor" =~ /\s(\w+),/p) { print "That actually matched '${^MATCH}'.\n"; } if("Hello there, neighbor" =~ /\s(w+),/p) { print "That was (${^PREMATCH})(${^MATCH})(${^POSTMATCH}).\n"; } 上面三个和$`,$&,$'是等价的 通用量词: /a{5, 15}/匹配a 5到15次 /(fred){3,}/匹配fred 3到无限次 /\w{8}/匹配w 8次 模式测试程序: #!/usr/bin/perl while(<>) { chomp; if(/YOUR_PATTERN_GOES_HERE/) { print "Matched: |$`<$&>$'|"; } else { print "No match: |$_|\n"; } } =cut
简单练习:
#!/usr/bin/perl =pod while(1) { chomp($line = <STDIN>); if($line =~ /a\z/) { print "Matched: |$`<$&>$'|\n"; } else { print "No match: |$line|\n"; } } =cut =pod while(1) { chomp($line = <STDIN>); if($line =~ /(\w*a$)/) { print "\$1 contains '$1'\n"; } else { print "No match: |$line|\n"; } } =cut =pod #ex8_3 while(<STDIN>) { chomp; if(/(\b\w*a\b)) { print "Matched: |$`<$&>$'|\n"; print "\$1 contains '$1'\n"; } else { print "No match: |$_|\n"; } } =cut =pod use 5.010; while(<STDIN>) { chomp; if(/(?<word>\b\w*a\b)) { print "Matched: |$`<$&>$'|\n"; print "'word' contains '$+{word}\n'"; #新的输出行 } else { print "No match: |$_|\n"; } } =cut =pod #ex8_5 m! (\b\w*a\b) #$1: 某个以字母a结尾的英文单词 (.{0, 5}) #$2: 后面接上的字符不超过5个 !xs #/x和/s修饰符 =cut #ex8_6 while(<>) { chomp; if(/\s\z) { print "$_#\n"; #井号在这里用作标示字符,表示行尾的位置。 } } system "pause";
不负自己