11ho 发表于 2015-12-26 09:24:09

Perl 中的 s/// 操作符

我们先来看一下 Perl 中的 s/// 操作符的用法:


    $var [=|!]~ s/pattern/replacement/ ;
  

程序1:


#!/bin/perl -w
use 5.010 ;

$s1 = '\n' ;
$s2 = "\n" ;
$s3 = "\\n" ;
say '$s1 = '."'\\n'" ;
say '$s2 = '.'"\n"' ;
say '$s3 = '.'"\\n"' ;
say '$_ = "123\nabc"' ;
say '********' ;
$_ = "123\nabc" ;
say 's/$s1/-/x' ;    # 1: 匹配
say s/$s1/-/x ;      # '\n' 直接被传递给了正则引擎,
                         # 正则引擎将 \n 解释为换行, 因此得到正确匹配
say ;                # 1230abc
say '--------' ;

$_ = "123\nabc" ;
say 's/$s2/-/x' ;    # 1: 匹配
say s/$s2/-/x ;      # "\n" 被 Perl 转义为一个换行符,
                         # 在选项 x 作用下被忽略为空,
                         # 因此匹配了字符串开头的空字符,
                         # 所以在字符串开头多了一个 0.
say ;                # 0123
say '--------' ;   # abc

$_ = "123\nabc" ;
say 's/$s3/-/x' ;    # 1: 匹配
say s/$s3/-/x ;      # "\\n" 被 Perl 转义为字符串 '\n' 并
                         # 传递给正则引擎, 正则引擎识别 \n 并解释为
                         # 换行, 因此得到正确匹配
say ;                # 1230abc
say '********' ;




  总结来说, 凡是使用变量作为 pattern 的时候, 都会经过 Perl 的转义.
  松散模式指的是, 在正则表达式中, 所有的空白符或者换行符都会被忽略, 但是变量中的不会.
程序2:



#!/bin/perl -w
use 5.010 ;

$s1 = '\n' ;
$s2 = "\n" ;
$s3 = "\\n" ;
say '$s1 = '."'\\n'" ;
say '$s2 = '.'"\n"' ;
say '$s3 = '.'"\\n"' ;
say '$_ = "123\nabc"' ;
say '********' ;
# pattern 为 \n 的情况下, 一定能够匹配
    # $_ 中的换行符, 因此, 我们
    # 只讨论 replacement 中的各种情况
$_ = "123\nabc" ;
say 's/\n/\n/x' ;   
say s/\n/\n/x ;      # 操作符直接看到 replacement 中的 \n,
                           # 不经过转义直接传递给正则引擎,
                           # 正则引擎识别 \n 为换行符并执行替换.
say ;                  # 123<Enter>
                     # abc
say '--------' ;   

$_ = "123\nabc" ;
say 's/\n/\\\\n/x' ;   
say s/\n/\\n/x ;       # 操作符直接看到 replacement 中的 \\n,
                           # 不经过转义直接传递给正则引擎,
                           # 引擎将 \\n 识别为.
                           # 一个反斜杠和一个字母 n
say ;                  # 123\nabc
say '--------' ;

$_ = "123\nabc" ;
say 's/\n/$s1/x' ;   
say s/\n/$s1/x ;       # '\n' 不被 Perl 转义, 作为两个字母传递给正则引擎,
                           # 正则引擎将这两个字母用于用 replacement.
say ;                  # 123<Enter>
                     # abc
say '--------' ;   

$_ = "123\nabc" ;
say 's/\n/$s2/x' ;   
say s/\n/+$s2+/x ;   # "\n" 被 Perl 转义为换行符并传递给正
                           # 正则引擎将转义后的换行符作用于
                           # 引擎的 replacement.
                           # 可见, x 选项不能作用于 replacement.
say ;                  # 123<Enter>
                     # abc      
say '--------' ;

$_ = "123\nabc" ;
say 's/\n/$s3/x' ;   # "\\n" 被 Perl 转义为一个反斜杠和一个字母 n,
                           # 并传递给正则引擎的 replacement,
                           # 引擎将 replacement 看到的两个字母
                           # 用于替换匹配的换行符.
say s/\n/$s3/x ;       # 123\nabc
say ;            
say '********' ;




  我认为, replacement 是没有经过 Perl 的变量转义, 直接在正则引擎替换了. 对于 x 选项, 我还有如下程序
  程序3:



#!/bin/perl -w
use 5.010 ;

$_ = "123\nabc" ;
say 's/\n/+<Enter>
+/' ;
say s/\n/+   
+/ ;          # 这说明 x 对 replacement 无效.   
                  # 但是依然将 replacement 中的换行符作用于替换中了,      
                           # 这说明 x 对 replacement 无效.   
say ;         # 123+<Enter>
                      # +abc





  
页: [1]
查看完整版本: Perl 中的 s/// 操作符