细究正则之任意字符

声明:从应用的角度来看,这篇博文的意义并不大,大可将宝贵的时间用在他处,因为匹配字符串很少会涉及到换行符"\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" =~ /^.$/;    # 不匹配; 需要一个非"\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" 不在字符串尾部

到此结束,有何错误之处,还请大家指正,小弟不胜感激!

英文链接:http://perldoc.perl.org/perlretut.html

原文地址:https://www.cnblogs.com/qingliuyu/p/1882229.html