用正则表达式处理文本
3.1 替换操作
3.1.1 用s///进行替换操作 (substitution)
- 如果把m//想象为文理处理器的字符串“查找”功能,那么s///就是查找并替换功能。
- 如:s/Barney/Fred/; 可以实现将Barney替换为Fred的处理。
- 与m// 和 qw//类似,s///也可以使用其他定界符
- 如:s{barney}{fred};s#barney#%fred%;
- 与m//类似,s///可以使用绑定操作符 =~
- m//和s///的区别:
- m//可以匹配任何字符串表达式;
- s///修改的数据必须预先存放在某个变量中;
- 这个变量一般位于该操作符的左边,也称作左值(lvalue)
- 如果匹配失败,什么也不会发生,原来变量里的内容不受影响。
- s///匹配替换成功返回真,否则返回假
#!/usr/bin/perl
$_ = "He is out with Barney tonight";
s/Barney/Fred/; #$_的值变为:"He is out with Fred tonight"
s/Wilama/Fred/; #$_的值不变,仍为:"He is out with Fred tonight"
#模式字符串 & 替换字符串可以更复杂
s/with (\w+)/against $1s team/; #$_的值变为:"He is out against Freds teram tonight"
# 下面是一些替换操作的例子:
$_ = "green scaly dinosaur";
s/(\w+) (\w+)/$2, $1/; #替换后为:"scaly, green dinosaur"
s/\A/huge, /; #替换后为:"huge, scaly, green dinosaur"
s/,.*een//; #空替换 :"huge dinosaur"
s/green/red/; #匹配失败:"huge dinosaur"
s/\w+$/($` !)$&/; #替换后为:"huge (huge !)dinosaur"
s/\s+(!\W+)/$1/; #替换后为:"huge (huge!)dinosaur"
s/huge/gegantic/; #替换后为:"genantic (huge!)dinosaur"
3.1.2 用/g修饰符进行全局替换
也许你已经注意到,s///只替换第一个匹配的字符串,这是s///默认行为,我们可以使用/g修饰符(global)实现全局替换。
- 除了/g之外,/i /s /x等模式修饰符同样适用于替换操作。
下例中给出几种常用的全局替换:
$_ = "home, sweet home"
s/home/cave/g; #$_的值变为: "cave, sweet cave"
#缩减空白
s/\s+/ /g; #将多个空白符转换为单一空格
s/\A\s+//; #将行首的多个空白删除;
s/\s+\z//; #将行尾的多个空白删除;
s/\A\s+|\s+\z//g; #将行首或行尾的空白删除;
3.1.3 s///的其他操作
(1)非破坏性替换
如果需要保留原始字符串和替换后的字符串,需要使用非破坏性替换
#!/usr/bin/perl
my $original = "Fred eat 1 rib";
(my $copy = $original) =~ s/\d+ ribs?/10 ribs/; #先执行括号内的赋值操作,后执行替换操作,替换的时$copy中的值
#v5.14之后 perl加入了/r修饰符,保留原来变量中的值不变,而将替换结果作为返回值。
my $copy = $original =~ s/\d+ ribs?/10 ribs/r; #绑定操作符=~优先级高于赋值操作=,先绑定后赋值
(2)大小写转换
在替换运算中,常常需要把所替换的单词全部换为大写或者小写,此时只需要用特定的反斜线定义就可以了。
转义符 | 举例 | 说明 |
---|---|---|
\U | s/(fred | barney)/\U$1/ |
\L | s/(FRED | BarNey)/\L$1/ |
\u | s/(fred | barney)/\u$1/ |
\l | s/(FRED | BARNey)/\l$1/ |
\E | s/(fred)(barney)/\U$1\E\u$2/ | \E表示\U的结束位置 |
\L\u | s/(FRED | BARNey)/\L\u$1/ |
- 大小写转换也可以使用perl中的内置函数
#!/usr/bin/perl
my $start = "Fred";