匹配
$var =~ m/pattern/flag;可省略m;!~是不匹配;没给出$var则默认对$_进行匹配;
修饰符flag:
i | 忽略大小写 |
m | 多行模式 |
s | 单行模式,.可以匹配换行符 |
x | 忽略模式中的空白,方便注释 |
g | 全局匹配 |
o | 仅编译一次 |
特殊变量:$`,$&,$',分别为匹配的字符串之前、本身、之后的字符。
替换
$var =~ s/pattern/replacement/flag;
flag:匹配有的flag都有,此外还有e:替换字符串作为表达式。
*如果对文件读出的内容进行替换,默认不会改变原文件内容,详细见修改文件内容。
转化
tr/string1/string2/flag;
flag:
c | 转化所有未指定的字符 |
d | 删除所有指定字符 |
s | 多个相同的输出字符缩成一个 |
如:
$string =~ tr/a-z/a-z/s; #把所有小写字母转换成大写,并且连续相同的字符只保留一个
$string =~ tr/\d/ /c; # 把所有非数字字符替换为空格
$string =~ tr/\t //d; # 删除tab和空格
$string =~ tr/0-9/ /cs # 把数字间的其它字符替换为一个空格。
元字符
\A | 只匹配字符串的开头 |
\z | 只匹配字符串的结尾 |
\Z | 只匹配字符串的结尾,和\z有区别 |
^ | 默认匹配字符串的开头,/m模式匹配行首 |
$ | 默认匹配字符串的结尾,/m模式匹配行尾 |
my $str1 = "abc
de
f";
#printf "%d\n",$str1 =~ m/^de$/; #匹配返回的是什么?
#if($str1 =~ m/^de$/) #sb,de那一行的开头是空格
if($str1 =~ m/^a/){ #匹配
print "match1\n";
}
if($str1 =~ m/f$/){ #匹配
print "match4\n";
}
if($str1 =~ m/e$/){ #不匹配,$默认匹配字符串尾
print "match2\n";
}
if($str1 =~ m/e$/m){ #匹配,/m模式下$匹配行尾,即多行模式
print "match3\n";
}
if($str1 =~ m/e\z/m){ #不匹配,无论加不加/m,\z都只匹配字符串的结尾
print "match5\n";
}
if($str1 =~ m/f\z/){ #匹配
print "match6\n";
}
if($str1 =~ m/\Aa/m){ #匹配,无论加不加/m,\A都只匹配字符串的开头
print "match7\n";
}
if($str1 =~ m/f\Z/){ #匹配,\Z能匹配字符串的结尾,和\z不同的是,结尾有没有终止子都匹配
print "match9\n";
}
my $str2 = "apple\n";
if($str2 =~ m/e\z/){ #不匹配
print "match10\n";
}
if($str2 =~ m/e\Z/){ #匹配
print "match11\n";
}
分组与捕获
1.用()括起来即分组,这样元字符可以作用于一个分组;
2.分组的字符串默认可以被反引,即捕获组。可以在模式匹配pattern中,或替换字符串replacement中使用。$n,\n,或\g{n}引用第n个捕获组的内容,从1开始,\g{-1}反向引用,-1为左边最靠近反向引用的编号;捕获组按左边括号的顺序排序。
$n | 可在模式匹配、替换字符中引用、或其他地方使用捕获组内容,不支持负值编号 |
\n | 可在模式匹配、替换字符(不推荐)中引用,其他地方不可,不支持负编号 |
\g{n} | 可在模式匹配中引用,其他地方不可,支持负值编号 |
3.(?:RE)为非捕获组,只分组,不捕获,即不能引用,除了命名捕获组为,其余的(?...)形式都是非捕获组。
4.(?<=string1)string2,前视界定,先有string1,才尝试匹配string2;string1(?=string2),后视界定,尝试匹配string1,其后必须跟string2;前视、后视是非捕获组。=换成!完成相反的功能。
5.捕获组命名:(?<index>RE)匹配RE,捕获的内容存放于%+的哈希中,index为key,使用捕获值:$+{index},模式匹配中引用捕获组:(?P<index>),或者\k<index>
my $str4 = "ababcdab";
if($str4 =~ m/(ab)\1/){
#printf "match:%s\n",\1; #\n是在模式匹配pattern中使用的,类型是引用。
printf "match1:%s\n",$1;
}
if($str4 =~ m/(ab)$1/){ #$1可以出现在模式匹配pattern中
printf "match2:%s\n",$1;
}
if($str4 =~ m/(ab)\g{1}/){ #\g{n}可以出现在模式匹配pattern中
printf "match3:%s\n",$1;
#printf "match3:%s\n",$-1; #不支持
}
#if($str4 =~ s/(ab)(cd)/\1\g{1}/){ #\g{n}不可以出现在替换字符串replacement中,\n可以。
if($str4 =~ s/(ab)(cd)/\1$1/){ #\n,$n可以出现在替换字符串replacement中,\n可以。
printf "match4:%s\n",$1;
print "$str4\n";
}
#(?<index>RE)命名捕获组,(?P<index>)引用明明捕获组,$+{index}使用捕获组
my $str1 = "jack and jack";
if ($str1 =~ /(?<first>\S+) (and|or) (?P<first>\S+)/) {
my ($first, $second) = ($+{"first"}, $+{first}); #{key}中加不加引号都行
print "$first\n$second\n"; # jack, jack
print "$&\n";
}
#\k<index>反向引用index命名捕获组
my $str4 = "ababcdab";
if($str4 =~ m/(?<index>ab)\k<index>/){
printf "match1:%s\n",$1;
}