声明:从应用的角度来看,这篇博文的意义并不大,大可将宝贵的时间用在他处,因为匹配字符串很少会涉及到换行符"\n"的。
之前也接触过正则表达式,但只停留在应用的层次上,对很多符号一知半解的。但正则对于校验数据的正确性立下汗马功劳,于是最近就花了一段时间专门研究perl语言中的正则表达式,看到任意字符".",竟然提起我的兴趣来。
任意字符"."可匹配除换行符"\n"以外的任意字符。而我之前就以为是匹配所有的字符,先bs自己一下!可为什么单独将换行符排除在外呢,孤零零的,perl官方的回答:The reason is that often one is matching against lines and would like to ignore the newline characters.不知如何翻译好,莫怪啊!下面就详细讲述"."与"\n"关系。
先让大家清楚perl语言中模式匹配的语法
$str="qingliuyu"; # 自定义变量,无须声明变量类型 $str =~ /liu/ # =~匹配操作符,//分隔符,liu程序员自定义的模式
"" =~ /^$/; # 匹配 "\n" =~ /^$/; # 匹配, $ 在"\n"之前的字符停止 "" =~ /./; # 不匹配; 需要一个字符 "" =~ /^.$/; # 不匹配; 需要一个字符 "\n" =~ /^.$/; # 不匹配; 需要一个非"\n"的字符 "a" =~ /^.$/; # 匹配 "a\n" =~ /^.$/; # 匹配, $ 在"\n"之前的字符停止
如果想匹配"\n",perl也为我们准备了//s和//m两种修饰符,//s指单行,将变量作为连续的字符串对待;//m指多行,将变量作为一个多行的集合对待。两种修饰符修饰的字符串,解析器对”.”表示的字符及”^”、”$”在何处匹配就会有区别。有四种情形:
- 没有修饰符(//):默认行为,”.”匹配除换行符”\n”以外的任意字符。”^”仅匹配字符串的头部,”$”匹配字符串的尾部或是尾部“\n”之前的部分。
- “s”修饰符(//s):把字符串作为单行对待,”.”就会匹配任意字符,包括”\n”。”^”仅匹配字符串的头部,”$”匹配字符串的尾部或是尾部“\n”之前的部分。
- “m”修饰符(//m):把字符串作为多行对待,”.”匹配除换行符”\n”以外的任意字符,”^”和”$”将分别匹配每一行的头部和尾部。
- “sm”修饰符(//sm):(//s)和(//m)的结合。”.”就会匹配任意字符,包括”\n”,”^”和”$”将分别匹配每一行的头部和尾部。
以例讲解:
$x = "There once was a girl\nWho programmed in Perl\n"; $x =~ /^Who/; # 不匹配, "Who" 不在字符串的开头 $x =~ /^Who/s; # 不匹配, "Who" 不在字符串的开头 $x =~ /^Who/m; # 匹配, "Who" 在字符串的开头 $x =~ /^Who/sm; # 匹配, "Who" 在字符串的开头 $x =~ /girl.Who/; # 不匹配, "."不匹配"\n" $x =~ /girl.Who/s; # 匹配, "." 匹配"\n" $x =~ /girl.Who/m; # 不匹配, "." 不匹配"\n" $x =~ /girl.Who/sm; # 匹配, "." 匹配"\n"
//m如果被用到,可以用\A匹配字符串的开头,用\Z匹配字符串的尾部(字符串的尾部或是尾部“\n”之前的部分,同“$”),\z就仅仅只匹配字符串的尾部(包括“\n”在内)
$x =~ /^Who/m; # 匹配, "Who" 在第二行的开头 $x =~ /\AWho/m; # 不匹配, "Who" 不在字符串的开头 $x =~ /girl$/m; # 匹配, "girl" 在第一行的尾部 $x =~ /girl\Z/m; # 不匹配, "girl"不在字符串的尾部 $x =~ /Perl\Z/m; # 匹配, "Perl" 在字符串尾部换行符之前 $x =~ /Perl\z/m; # 不匹配, "Perl" 不在字符串尾部
到此结束,有何错误之处,还请大家指正,小弟不胜感激!