Perl中的正则表达式

 
1. 使用简易模式
如果匹配对象是$_的内容。只要把模式写在一对//中就可以。即m//简写
$_="Fred"
if (/fred/) {
#...
}
 
2. 元字符
. 匹配任何单一字符,\n除外。
如果要想包含\n在多行匹配,需要用\s来代替.
如果想让.表示字面意义,需要用\. ,例如/3\.14159/
*
+
?
()模式分组,例如/(fred)+/会匹配fredfredfred
表达式后面的字符可以使用\1,\2...\n调用前面的模式分组(反向引用)。例如匹配两个相同的字符。注意序号是严格按左括号出现的位置进行判定。
$_="abba"
if(/(.)\1/) {
print "it matched same character next to itself!\n";
}
print "matched" if (/(.)(.)\2\1/); #专门匹配abba这样的回文字符
嵌套的模式分组:
$_"yabba dabba doo";
print "matched" if (/y((.)(.)\3\2) d\1);
展开分析
y( #第一个左括号\1
(.) #第二个左括号\2
(.) #第三个左括号\3
\3
\2
这样就可以匹配 yabba dabba的字符串
perl会尽可能多的尝试反向引用的数字号,当出现\111,perl会尝试\111如果不存在111组,则失败。为了排除二义性,使用\g{1}11来引用第一组。\g{-1}可以用相对位置,-1表示刚才的位置。
例如print “matched” if(/(.)\g{-1}11/)
| 注意|的优先级很低,所以/^begin1|begin2/表示词从begin1开始或者单单匹配begin2.所以|运算符和括号是天生的一对。
[a-zA-Z0-9]
[^n\-z] 这一这里的连字符需要加上反引线
[\000-\177] 注意方括号字符集中的\num符号是ASCII码值,而非反向引用的模式分组号。
\d 数字字符集等同与[0-9]
\w 单词字符集 等同与[a-zA-Z0-9_].所以\w+通常可以表示一个单词。
\s 空白符集 等同与[\f\t\n\r ]换页,制表,换行,回车以及空格。
\h 横向空白符集,即[\t ]
\v 纵向空白符集,即[\f\n\r]
\V 非垂直空白符
\H 非水平空白符
[^\d][^\w][^\s] 非数字,单词和空白符模式
[\du-z] 字符集符号嵌套写入其他[]字符集里
^$
\b 单词锚位,等同与ERE标准中的\<和\>
{m}
{m,}
{m,n}
其他:
'\t' : 制表符(HT, TAB)
'\n' : 换行(LF, NL)
'\r' : 回车(CR)
'\f' : 进纸(Form Feed, FF)
'\a' : 报警 (Alarm, BEL)
'\e' : 转义(ESC)
"\0xx" : 八进制数值对应字符,如\033表示ESC
"\xhh" : 16进制数值对应字符,如\x1B表示ESC
"\x{hhhh}" : 16进制long型数值对应字符,如\x{263a}表示unicode SMILEY
"\cK" : K可以为任意字母,表示控制字符"control-K","\cK"表示如VT
"\N{name}" : unicode命名字符
"\N{U+hhhh}" : unicode字符
'\l' : 小写下一字符
'\u' : 大写下一字符
'\L' : 小写随后字符串直至'\E'
'\U' : 大写随后字符串直至'\E'
'\E' : 结束大小写转换
'\Q' : 引用随后字符(禁止转义)直至'\E'
'\w' : 匹任任一单词(word)字符(26个英文字母、10个数字,加下划线'_')
'\W' : 匹配任一非单词字母
'\s' : 任一空白字符(空格' ', 制表符'\t'等)
'\S' : 任一非空白字符
'\d' : 任一数字字符[0-9]
'\D' : 任一非数字字符
“\pP” : 匹配命名属性P
"\PP" : 匹配非P
'\X' : 匹配unicode扩展字符集(eXtended grapheme cluster)
'\C' : 匹配单个C字符(字节),即使工作在unicode模式下
'\n' : n为数字,后向引用指定组n
"\gn" : 后向引用指定组n
"\g{-n}" : 表示相对(当前位置之前的)第n个后用引用组n
"\g{name}" : 后向引用命名组(name)
"\k{name}" : 后向引用
'\K' : 使\K左侧部分,不引入到$&中
'\N' : 除'\n'外的任一字符
 
'\R' : 行分割符号
POSIX字符类表示语法:[:class:], 在pattern中则必须写为"[[:class:]]"。
"[[:alpha:]]" : (英文)字母
"[[:alnum:]]" : 字母或数字字符
"[[:ascii:]]" : ASCII字符集中字符
"[[:blank:]]" : GNU扩展,等价于空格' '或水平制表符'\t'
"[[:cntrl:]]" : 任一控制字符
"[[:digit:]]" : 任一数字字符,等价于'\d'
"[[:graph:]]" : 除空格外的任一可打印字符
"[[:lower:]]" : 任一小写字符
"[[:print:]]" : 任一可打印字符,包括空格
"[[:punct:]]" : 除单词字符(字母,'_')外的任一图形字符
"[[:space:]]" : 任一空白字符,等价于'\s'垂直制表符"\cK"
"[[:upper:]]" : 任一大写字符
"[[:word:]]" : Perl扩展, 等价于'\w'
"[[:xdigit:]]" : 任一16进制数字
Assertion
'\b' : 单词边界
'\B' : 非单词边界
'\A' : 字符串首
'\Z' : 字符串尾或尾部换行字符之前
'\z' : 字符串尾
'\G' : 在上一个匹配处进行匹配
 
所有基本的量词*,+,?,{}都是贪婪量词(匹配尽可能多,即从行的末尾开始来找下面的模式。)
占有式:同贪婪量词,尽可能多地匹配字符,但是从行的末尾来下面模式的过程中,绝不回退。用+来表示占有是量词。
非贪婪量词(或者叫最小匹配mnimum),所有量词后面加上?号。(下面的模式从下面出现的第一个开始匹配)
例如s#<BOLD>(.*)</BOLD>#$1#g
上面使用贪婪模式将会是灾难,因为一行中可能出现多个</BOLD>。将*改为*?
 
 
4.可选修饰符(可以组合,例如/isx)
/i 忽略大小写
/s 使用.匹配任意字符,包括换行。用于多行匹配情况。
/x 模式中可以加入任意空格和制表符,方便阅读。而真正的空格或者制表符就需要\
注意:注释也算一种空白。所以/x可以加上注释。当需要真正#号时需要\#
/
-? #0个或1个-号
\d #一个或多个数字
...
/x
 
5. 绑定操作符=~ 用右边的模式来匹配左边的字符串。而非匹配$_
print "Hey, there's a rub" if($str=~/\brub/);
print "you input yes!" if(<STDIN>=~/\byes/); #用于判定输入很方便
 
6. 可以将双引号变量插入到模式串中。例如
my $name="larry";
while (<>) {
if(/^($what)/) {
print "matched\n";
last;
}
}
不停输入,直到输入到想要的为止。
7. 捕捉变量$1,$2,...,$n分别代表模式串第几个()中匹配到的字符串
例如
my $dino="I fear that I'll be extinct after 1000 years.";
if($dino=~/(\d*) years/) {
print "That said '$1' years.\n";
}
else{
print "They don't have a year";
}
捕捉变量的生命期:直到下一次成功的匹配为止。失败的匹配不会更改捕获的内容。
(?:)声明不捕捉这个括号:/(?:thiswillnotbecaught).*(thiswillbe$1)/
命名匹配 (?<name1>\w+),
例如:m/(?<name1>\w+) (?:and|or) (?<name2>\w+)这时会引入一个特殊的哈希%+,那么访问命名捕捉就可以直接使用$+{name1},$+{name2}
自动匹配变量:$&匹配的整个段落,$`匹配其实位置之前的字符串,$'匹配之后位置的字符串,所以print $`, $&, $'就是整个字符串。但是,如果程序的任何部分使用了自动匹配变量,其他正则表达式的运行速度也会变慢。所以使用别的方法(例如将整个模式加上括号,然后用$1来代替$&)比较靠谱。
 
7.正则表达式的文本处理
s/// 等同与s{fred}{barney} s[fred](barney) s<fred>#barney#
/igsx
/m multiple lines。这时候^$表示其中每行的开头和结尾。
例如: $_"I'm much better\nthan you"
print "Find 'than' in the begin of the line" if /^than\b/im 
\U \u 转换符后所有的字符都将转换为大写,例如/\U$1/那么$1将变为大写。小写只影响后面第一个字符
\L \l 转换符后所有的字符都将转换为小写。小写只影响后面第一个字符。
\E \E结束大小写转换的影响。/\U\1\E\2/只影响\1
@split 根据分割符拆开一个字符串。这对处理被制表符,冒号,空白或者任意字符分割的数据很有用。
@field = split /separator/, $string
@fields = split /:/, ":::abc:def:g:h:::" 得到"" "" "" "abc" "def" "g" "h" 后面的空模式将被省略
join 同split恰恰相反,split会将字符串分解未数个片段。join会将这些连结到一些
my $result = join $glue, @pieces;
m// in list context
返回的是符合模式的字符串的列表
例如my @words = ($text =~ /[a-z]+/ig)
print "Result: @words\n";
一次更新多个文件:
#!/usr/bin/perl -w
use strict;
chomp(my $date=`date`); #或者使用my $date=localtime
$^I=".bak" 设置这个变量,则会自动以此打开多个文件
while(<>) { #默认的钻石运算符是读取@ARGV数组的内容
s/^Author:.*/Randal/;
s/^Phone:.*\n//;
...
print;
}
 
 
Textbook: Learning Perl