perl学习日记9使用正则表达式处理文件

1.    使用正则表达式处理文件

1.1      使用s///进行替换

$_ =“He’s out bowling with Barney tonight.”;

s/Barney/Fred/; #Barney Fred 替换掉

print “$_/n”

 

s/with (/w+)/agaist $1’s team/;

print “$_/n”; #“He’s out bowling against Fred’s team tonight”;

 

$_ =“green scaly dinosaur”;

s/(/w+) (/w+)/$2, $1/; #现在为“scaly, green dinosaur”;

s/^/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/gigantic/; #现在为“gigantic (huge!) dinosaur”

 

s///会返回一个Boolean 值。如果成功替换则返回true;否则返回false

1.1.1.使用/g 进行全局替换

$_ = “home, sweet home!”;

s/home/cave/g;

print “$_/n”; # “cave, sweet cave!”;

 

$_ =“Input data/t may have extra whitespace.”;

s//s+/ /g; #现在是“Input data may have extra whitespace.”

 

s/^/s+//; #将开头的空白去掉

s//s+$//; #将结尾的空白去掉

1.1.2.不同的分隔符

s#^https://#http://#;

如果使用的是配对的字符,也就是说其左字符和右字符不的,则必需使用两对:一对存放模式,一对存放替换的字符串。

s{fred}{barney};

s[fred](barney);

s<fred>#barney#;

1.1.3.可选的修饰符

s#wilma#Wilma#gi; #将所有的WilmA,或者WILMA 等等,由Wilma 替换掉

s{_ _END_ _.*}{ }s; #END 标记及其后面的行去掉,记住/i /s /x /g

1.1.4.绑定操作

$file_name =~ s#^#/##s; #$file_name最前面加#号。注意每个#的含义

1.1.5.大小写转换

$_ =“I saw Barney with Fred.”;

s/(fred|barney)//U$1/gi; #$_现在是“I saw BARNEY with FRED.”

 

s/(fred)|barney//L$1/gi; #$_现在是“I saw barney with fred.”

 

s/(/w+) with (/w+)//U$2/E with $1/I; #$1 现在是“I saw FRED with barney.”

 

s/ (fred|barney)//u$1/ig; #$_现在是“I saw FRED with Barney.”

 

也可以同时使用它们。如使用/u /L 表示“第一个字母大写,其它字母均小写”◆:◆/L /u 可以按任意顺序出现。Larry 意识到人们有时可能按相反顺序使用它们,因此他将Perl 设计成,在这两种情况下都是将第一个字

母大写,其余的小写。Larry 是个非常好的人。

s/(fred|barney)//u/L$1/ig; #$_现在为“I saw Fred with Barney.”

这些在替换中出现的大小写转换的修饰符,也可在双引号中使用:

print “Hello, /L/u$name/E, would you like to play a game?/n”

 

1.2      split 操作

@fields = split /:/, “abc:def:g:h”; #返回(“abc”, “def”, “g”, “h”)

@fields = split /:/,“abc:def::g:h”; #得到(“abc”, “def”, “”, “g”, “h”)

这里有一条规则:开头的空元素会被返回,但结尾的空元素被丢弃

@fields = split /:/, “:::a:b:c:::”; #得到(“”, “”, “”, “a”, “b”, “c”;

 

my $some_input = “This is a /t test./n”;

my @args = split //s+/, $some_input; #(“This”, “is”, “a”, “test.”)

 

默认时,split $_操作,模式为空白:

my @fields = split; #split //s+/, $_

1.3      join 函数

my $x = join“:”, 4, 6, 8, 10, 12; #$x “4:6:8:10:12”

 

my @values = split /:/, $x; #@values (4, 6, 8, 10, 12)

my $z =join “-”, @values; #$z “4-6-8-10-12”

 

1.4      列表上下文中的m//

返回的是$1 $2 $3…

my $text = “Fred dropped a 5 ton granite block on Mr. Slate”;

my @words = ($text =~ /([a-z]+)/ig);

print “Result: @words/n”;

#Result: Fred dropped a ton granite block on Mr slate

 

my $data = “Barney Rubble Fred FlintstoneWilma Flintstone”;

my %last_name = ($data =~ / (/w+)/S+(/w+)/g);

 

每当模式匹配成功时,将返回一对值。这些一对一对的值就成了hash 中的key/value 对。

1.5      更强大的正则表达式

1.5.1.非贪婪的数量词

fred and barney went bowling last night barney 上使用/fred.+barney/进行匹配

如果真如书上说,用回退的方式匹配,则匹配的应该是整个句子了,做个实验!!实验表明的确是这样

 

现在我们来看看模式为/fred.+?barney/时的过程

将贪婪改成了非贪婪,应该匹配的是前面部分,binggo

 

要删掉body标记:

I thought you said Fred and <BOLD>Velma</BOLD>, not <BOLD>Wilma</BOLD>

$#<BOLD>(.*?)</BOLD>#$1#g; #正确,改成了非贪婪,匹配最先发现的</BOLD>

如果没有?贪婪的话就留下了中间两个

 

花括号的非贪婪类型看起来一样,只是在闭花括号后有一个问号,如{5,10}?或者{8,}?◆。甚至问号数量词也有非贪婪类型:??。它匹配一次或者次,但倾向于匹配次。

 

1.5.2.匹配多行文本

$_ =“I’am much better/nthan Barney is/nat bowling,/nWilma,/n”;

print “Found ‘wilma’at start of line/n”if /^wilma/b/im;

锚定^$是指整个字符串的开头和结束(参阅第八章)。但/m 这个正则表达式选项允许它们根据内部的换行符进行匹配(将m看作多行(think m for multiple lines))。这时锚定针对每一行,而非整个字符串。因此,这个模式可以匹配上

 

将文件名字加在每一行的开头处:

open FILE, $filename

or die “Can’t open ‘$filename’: $!”;

my $lines = join '', <FILE>;

$lines =~ s/^/$filename: /gm;

1.5.3.更新大量文件

#! /usr/bin/perl –w

use strict;

chomp(my $date = ‘date’);

$^I =“.bak”;    #如果没有它,<>得到的$_在被改变时是不会改变原输入文件的,但是有了它就会改变,同时生成以“.bak”为后缀名的备份文件备份原来的文件,若它的值是空串,则不会产生备份文件,而直接改变原文件的内容

while(<>){

s/^Author:.*/Author: Randal L. Scharwartz/;

s/^Phone:.*/n//;

s/^Date:.*/Date: $date/;

print;

}

 

这个例子好有用,要实验好好探讨

1.5.4.在命令行中进行修改

$perl –p –i.bak –w –e ‘s/Randall/Randal/g’fred*.dat

意思就是执行批量替换,原来的放在.bak的备份文件里,也可以

perl -pi -e "s/oldstring/newstring/g"

这样就不备份

1.5.5.     非捕捉用的括号

if(/(bronto)?saurus (steak|burger)/)   #我不想bronto存在$1里,但是此时又不能不加括号,怎么办?

{

print “Fred wants a $2/n”;

}

和下面的区别

if(/(?:bronto)?saurus (steak|burger)/)    #这样就把括号改成了非捕捉用的了,自然bronto就不会存在$1

{

print “Fred wants a $1/n”;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值