我今天遇到了这个Perl构造:
@foo = split("\n", $bar);
这适用于将大型字符串拆分为UNIX类型行结尾的行数组,但为Windows留下了尾随\ r \n.所以我改成了:
@foo = split("\r?\n", $bar);
其中逐行拆分字符串并且不留下尾随\ r \n(在ActivePerl 5.8下测试).然后有人向我指出,这应该是:
@foo = split(/\r?\n/, $bar);
那么为什么第二种变体会起作用呢?双引号意味着评估内容,这就是为什么\ r和\n实际上被视为CR和LF,但是?被视为正则表达式元字符而不是文字问号.
正则表达式周围的斜杠是split()的可选项吗?是否假设函数的第一个参数是正则表达式?
斜杠只是正则表达式的标准分隔符(您可以使用其他分隔符),它们像双引号一样评估特殊字符和转义序列.
编辑:我拍摄得太快,正如曼尼在评论中解释的那样.我会尝试更长的解释:
通常,Perl中匹配的正则表达式以m开头,然后将正则表达式主体括在某个分隔符中.匹配正则表达式的标准分隔符是斜杠,m
如果使用斜杠作为分隔符,则可以省略前导:
m/\r?\n/ m"\r?\n" m$\r?\n$ /\r?\n/
这些都是一样的,它们被称为"正则表达式文字".如果使用单引号,则不会对转义序列进行求值.
在这一点上,你的第一次尝试,双引号中的正则表达但没有前导m
,似乎很奇怪,但是,正如Arnshea所解释的那样,这split
是一个特例,因为它接受正则表达式不仅仅是一个文字,而是也作为一个字符串.
您可以将正则表达式作为字符串或正则表达式文字传递.所以将它作为双引号字符串传递是好的.
您还可以使用标准/正则表达式/以外的字符来分隔正则表达式文字
是的,split总是采用正则表达式(包含单个空格特殊情况的字符串除外).如果你给它一个字符串,那将用作正则表达式.同样的事情发生在=〜(例如$ foo =〜"pattern").无论是否使用//,正则表达式元字符都将被视为处理.
这就是为什么总是使用//来强调它有时候不是文字字符串或者有时是正则表达式的原因所以你不小心尝试拆分("|","a | b | c")有一天.