Perl笔记:Perl语言入门(第六版) - 正则表达式、字符串

来源:互联网 发布:如何打开淘宝我的店铺 编辑:程序博客网 时间:2024/04/27 14:03

匹配

使用简单模式

如果匹配对象$_,则只需把模式写在一对斜线中就可以。模式匹配通常返回布尔值。

$_ = "yabba dabba doo";

if (/abba/) {

print "It matched!";

}

根据字符属性匹配

Unicode字符可以理解自身含义,可以通过字符属性名匹配,空白符\p{Space}、数字\p{Digit}、十六进制\p{Hex},p改为大写表示否定\P{Space}非空白符。

元字符

前置反斜线,可取消元字符的特殊作用。


通配符 . 除换行符外的所有字符

量词 * 重复任意次

量词+ 至少一次

量词? 零次或一次

模式分组 () 对字符分组,可捕获匹配文字

反向引用 \1 引用圆括号中模式匹配的文字,称为捕获组,数字与顺序对于。

择一匹配 |

字符集[] - 可以使用连字符-表示范围。

字符集简写 \w \s \d

反义简写字母大写 \D <==>[^\d]\W,\D

匹配所有包括换行符[\d\D]

\A锚位匹配字符串开头

\z匹配字符串绝对末尾

\Z匹配字符串末尾,允许后面出现换行符

^行首锚位 字符串开头和换行符下一个字符。需要和/m配合,没有/m时,和\A相同

$行末锚位

\b 单词边界锚位

反向引用

可以用反向引用再次匹配刚刚匹配的字符。

例:

$_ = “abba”;

if (/(.)\1/) { #匹配bb

}

反向引用的编号,依照左括号的顺序排列。

5.10开始,支持新的反向引用写法,使用\g{N},N指定反向引用的组号。

可以使用负数进行相对反向引用,相对引用符号所在的位置。

模式匹配操作符m//

 双斜线是m//的简写。定界符也可自定,但使用双斜线可以省略m。

修饰符

/i 不区分大小写

/s 匹配任意字符 - 将模式中出现的所有.修改为匹配所有字符

/x 可以在模式中随意添加空白符

/a 按照ASCII范围匹配字符

/u 匹配任何unicode字符

/l 本地化字符

/p 启用自动捕获变量

绑定操作符 =~

默认情况下,模式匹配的对象时$_,绑定操作符告诉Perl,匹配左边的字符串

if ($some =~ /\brub/) {

}

模式中的内插

my $what = shift @ARGV;

while (<>) {

if ( /\A($what)/) {

}

}

输入的正则表达式可能非法,需要捕获错误进行处理。

捕获变量

圆括号出现的地方一般都会触发正则表达式捕获匹配到的字符串。捕获组会把匹配的字符串保存起来,可以通过反向引用取得捕获内容,也可以在匹配结束后通过捕获变量取得内容。

捕获变量的形式:$1,$2

捕获变量通常存活到下次匹配成功为止。匹配失败不会改动上次成功的匹配。

不捕获模式(?:)

命名捕获(?<LABEL>PATTERN)

命名捕获的捕获变量$+{LABEL}

命名捕获的反向引用\g{LABEL}

例:

use 5.010;

my $name = 'Fred or Barney';

if ( $name =~ m/(?<name1>\w+) (?:and|or)(?<name2>\w+ ) {

say "I saw $+{name1} and $+{name2};

}

自动捕获变量

$& 字符串实际匹配的部分

$` 匹配区段之前的内容

$' 匹配区段之后的内容

5.10或以上版本,使用修饰符/p启用类似的自动捕获变量${^PREMATCH}、${^MATCH}、${^POSTMATCH}

通用量词

{5,15} 5-15

{3,} 重复三次或以上

{8} 重复8次

优先级

圆括号 (), (?:), (?<LABEL>)

量词 *, +, ?, {1,5}

锚位和序列 abc, ^, $, \A, \b, \z, \Z

择一 a|b|c

原子 a, [abc], \d, \1, \g{2}

处理文本

用s///进行替换

$_ = "He's out bowling with Barney tonight.";

s/Barney/Fred/;

print "$_\n";

s///返回布尔值,替换成功时为真。

可以定义定界符,对成对字符必须使用两对,一对包住模式,一对包住替换字符串

用/g进行全局替换

s///默认执行一次替换,/g修饰符可以替换所有的可能。

无损替换

(my $copy = $original) =~ s/\d+ ribs?/10 ribs/;

my $copy = $original =~ s/\d+ ribs?/10 ribs/r; #默认s///操作完成后返回成功替换的次数,加上/r后会保留原字符串值不变,而把替换结果作为返回值。

大小写转换

\U将其后所有字符转为大写

\L将其后所有字符转为小写

\E关闭大小写转换

s/(\w+) with (\w+)/\U$2\E with $1/i;

\u, \l其后一个字符转为大小写

转换可以并用,\u\L,首字母大写其余小写,可用在任何双引号字符串中。

split操作符

根据给定的模式拆分字符串

my @fields = split /:/, "abc:edf::g:h"; #("abc", "def", "", "g", "h")

相连的分隔符产生空字段,保留开头的空地段,但会舍弃结尾的空字段。

默认使用空白符分割$_中的字符串:split <==> split /\s+/, $_;

join函数

join不使用模式,功能和split相反,连接字符片段

my $x = join ":", 3, 4, 5, 5, 10; #"3:4:5:5:10", 第一个参数为字符串

列表上下文中的m//

列表上下文中使用模式匹配操作符时,如果匹配成功,返回所有捕获的变量的列表,失败返回空列表。

my @words = ($text =~ /([a-z]+)/ig); #匹配并返回单词列表,类似split,但模式匹配相反,模式指定想要留下的部分。

更强大的正则表达式

非贪婪量词

前述的四个量词都是贪婪量词,会匹配尽量长的字符串。对应的非贪婪版本+?, *?, ??, {4, 10}?

跨行的模式匹配

在/m修饰符下,^ $可以匹配行首位,配合/g可以全局匹配所有模式。

一次更新多个文件

<>钻石操作符可以自动打开多个文件,如果没有指定文件就会从标准输入读取数据。

$^I默认值是undef,如果赋值,该字符串就会变成备份文件的扩展名,原文件名添加后缀。如果为空字符串就会直接修改文件内容,而不备份。

从命令行直接编辑

perl -p -i.bak -w -e 's/Randall/Randal/g' fred*.dat

-p选项可以让Perl自动生成一小段程序,类似while (<>) {print;},可以改用-n选项,执行时会去掉print

-i.bak 程序运行之前把$^I设为".bak",不要备份可以直接写出-i

-w开启警告

-e说明后面跟着的是可供执行的程序代码,可以指定多个-e选项,最后一段程序末尾的分号可以省略。

字符串

index

查找子串在主字符串中的相对位置

$where = index($big, $small); #在$big字符串中寻找$small字符串首次出现的地方,返回整数表示的首字符匹配位置,从零算起。

可以使用可选的第三个参数指定开始搜索的位置。没找到时返回-1。

rindex函数从后到前搜索。

substr

从字符串中截取一段子字符串

my $rock = substr "Fred J.Flintstone", 13, 1000; #返回stone。

参数 原始字符串、从零算起的起始位置、子串长度。超出原字符串结尾得到短的字符串,如果需要到字符串结尾,可省略第三个参数。

第二个参数可以为负值,表示从字符串结尾倒数,最后一个字符串为-1。

可用于修改原字符串

my $string = "Hello, world!";

substr($string, 0, 5) = "Goodbye"; #$string现在的值为"Goodbye, world!",字符串会自行调整长度。

功能相同的另一种写法: my $previous_value = substr($string, 0, 5, "Goodbye");

可与绑定操作符配合使用,下例只替换最后20个字符:

substr($string, -20) =~ s/fred/barney/g;

sprintf

和printf类似,返回字符串。 my $date_tag = sprintf "%4d/%02d/%02d %2d:%02d:%02d", $yr, $mo, $da, $h, $m, $s;

非十进制数字字符串转换

hex() 十六进制数转换为十进制

oct()八进制转为十进制,以十六进制或二进制前缀开始的字串也可正确转换,但前缀不能省略。

hex('DEADBEEF') #3_735_928_559

hex('0xDEADBEEF'); #3_735_928_559

oct('0377') #255

oct('377')  #255

oct('0xDEADBEEF');   #3_735_928_559

oct('0b1101') #13

oct("0b$bits") #将$bits当作二进制转为十进制

排序

高级排序

排序子程序,会被多次调用。用于确定两个元素的顺序,$a和$b是自动赋值的待排序列表元素。

sub by_number {

if ($a < $b) {-1} elsif ($a > $b) {1} else {0}

}

排序过程: my $result = sort by_number @some_numbers;

排序子程序的简写

sub by_number {$a <=> $b}

<=> 比较两个数字并返回-1、0、1

对应的字符串比较:cmp

不区分大小写的排序

sub case_insensitive { "\L$a" cmp "\L$b" }

简单的排序,子程序也可以内嵌到排序子程序名的位置,如下:

my @strings = sort { $a cmp $b } @some_strings; #和sort默认排序方式相同。

递减排序可使用reverse函数:my @descending = reverse sort { $a <=> $b} @some_numbers;

也可调整$a和$b的位置:my @descending = sort  { $b <=> $a } @some_numbers;

哈希值排序

my %score = ("barney" => 195, "fred" => 205, "dino" => 30);

my @winners = sort by_score keys %score; #哈希是无法排序的,仅是对哈希键的名称进行排序。

sub by_score { $score{$b} <=> #score{$a} } #排序子程序

按多个键排序: sub by_score_and_name {$score{$b} <=> $score{$a} or $a cmp $b }

0 0
原创粉丝点击