美文网首页
2020-03-19 perl 中正则匹配总结

2020-03-19 perl 中正则匹配总结

作者: Bio小盼 | 来源:发表于2020-03-19 22:53 被阅读0次

一般用法:匹配字符串,变量

$_="yabba dabba doo";
if(/abba/){##默认用它匹配$_中字符串
  print "it matched!\n";##可以匹配,
}
##匹配过程;过程从$_第一字母开始,尝试依次匹配,可以匹配一次即为匹配成功,不在继续进行(局部匹配)
##注意::若果改写为/abb a/ 中间空格也是需要匹配到,if才能返回TRUE

$pattern="(";
if(/$pattern/){
  print "it matched!\n";
}

if(//){
  print "it matched\n";##这样写啥都可以匹配成功
]

通配符

  • 点号 :匹配除换行符以外的任意单个字符,包括符号,eg:!
  • \N: 同点号,可以匹配除换行符以外的任意单个字符
$_="yabba dabba doo!";
if(/doo\N/){ ##写法同if(/doo./)
  print "it matched\n";  ##结果是可以匹配,因为有!的存在
}

量词(重复次数,或者重复操作符)

  • 功能:用量词来指定匹配项的重复次数
  • 量词种类:
    • ?:前一个字符可有可无
$_="Bamm-bamm";
if(/Bamm-?bamm/){
    print "it matched\n";##b前面-可有可无
}
  • * :前一个字符可有可无且重复次数不定
  • +:前一个字符至少出现一次
$_="Bamm       bamm";
if(/Bamm +bamm/){##b前面至少出现一次空格
    print "it matched\n";
}

$_="yabbbba dabbba doo.";
if(/ab{3}a/){##匹配连续出现三次b,两侧为a,即:dabbba
    print "it matched\n";
}

$_="yabbba dabbba doo.";
if(/ab{2,3}a/){##b至少出现两次,至多出现3次
    print "matched\n";
}
if(/ab{3,}a/)#b至少出现3次,没有上限

小结::

? 前一个字符可有可无
* 前一个字符0次或多次
+ 前一个字符一次以上
{3,} 前一个字符出现至少三次不设上限
{3,5} 前一个字符出现至少三次至多5次

20200324更:

模式分组

  • 捕获分组:括号围起来的分组
  • 反向引用写法:反斜线后面接上数字,每个数字代表对应的捕获分组
    • 反向引用注意事项:不用紧贴对应捕获分组后面
  • 例子:1.匹配连续出现两个同样的字符 2.y后面的几个字符在b后面也出现一次 3.\g{N}写法
    • \g{N}:
      • N代表原来\后面的数据编号,亦可以简写为\gN
      • \g{-1}:表示反向引用左侧最靠近它的位置
#eg1:
$_="abba";
if((.)\1){ ##能匹配bb
  print "matched";
}
##(.)\1 意思为连续出现两个同样的字符

#eg2:
$_="yabba dabba doo";
if(y(....)d\1){ ##匹配到yabba dabba
  print "it matched";
}
if((.)(.)\2\1){ ##匹配镜面重复类eg:abba 其中\2代表匹配第二括号中内容,\1代表匹配第一括号中内容
  print "";
}

#eg3:g{N}写法
$_="aa11bb"; #若果想匹配11前面有一个重复的字符
if((.)\111){##这种写法有歧义,是匹配任意字符11次后面有1,还是匹配任意字符111次??
}
#为正确匹配修改写法为
if((.)\g{1}11){##\g{N}写法含义:N代表原来\后面的数据编号
}
if((.)(.)\g{1}11){#会与上面匹配到相同的内容
}

择一匹配

$_="fred \t \t barney";
if(fred( |\t)+barney){#fred与barney中间存在\t或者空格可以匹配
}

字符集

  • 指在单个位置上能匹配的各种模式字符的集合,eg:[agjoexsg]只要在某个位置出现其中任意一个字符,就能匹配成功,
    • 字符集中点号代表其本身
    • 不匹配n到z任意一个字符:[n-z],不匹配a和-,任意一个字符:[n-z],不匹配a和-:[^a-]
  • 简写(改为大写,即为非):
    • \s:任意空白字符 \S:非空白字符
$_="fred \t \t ba";
if(/fred\s+ba/){
}
  • \h:匹配水平空白字符
  • \d:匹配任意数字
  • \w:匹配任意单词
  • \R:任意种类换行符

锚位

  • 开头:\A 或者 ^
  • 行末结尾:\Z
  • 决定结尾:\z
$_="http:www.ablcdeg.com";
if(/\Ahttp*com\z/){##匹配http开头,com结尾
}
#匹配空行:
if(/\A\s*\Z/){
}

单词锚位

  • \d:单词边界锚位,
    eg:/\bfred\b/:需要匹配单词fred,fredd、adfred均不能匹配
    /\bfred\B/:可以匹配fredd,但不匹配fred、adfred

用正则表达式进行匹配

  • 定界符:
    使用成对字符,中间加正则表达式内容 eg:m/fred/,m%fred\%(\不用转义,会匹配fred\),m{fred},m[fred]
    +注意:使用//时,可以省略m,较为常用的是//,{}
  • 模式匹配修饰符
    • 定义:正则表达式末尾追加的可以调整模式匹配的用来修饰的字符,别名:flag
    • 种类
      1. \i:大小写无关匹配
      2. \s:匹配任意字符:功能:可以换行匹配,字符串中包含换行符,且希望点号能匹配换行符,结合\s可实现此功能
$_="i saw bareny\ndown at the bowling alley\n with Fred\nlast night.\n";
if(/bareny.*Fred/s){}
#如果没有\s就不能匹配,因为它们没有在一行
  3. \x:加入辅助空白字符,作用:分割匹配内容,使更易读
/-? [0-9]+ \.? [0-9*]/
  4. 联合使用修饰符:若单次使用多项修饰符,可将其连在一起写在末尾
/barney.*fred/is  

捕获变量

  • 正则表达式会捕获()中匹配的内容,并保存至相应变量,
  • 取得捕获内容
    + 反向引用取得捕获内容,
    + 匹配后,通过对应的捕获变量取得这些内容。
    + 匹配模式中有n个(),那么最后一个匹配内容对应$n.
    + 捕获到的内容会保存在特殊哈希%+中,键为:捕获时的标签,值为被捕获的字符串,具体写法:(?<LABEL>PATTERN),具体请看例子
  • 不对()捕获变量:假如不想捕获括号中某个字符,可以(?:bronto),表示不会捕获此变量
my $_="fred or barney";
if(/(?<name>\w+)  (?:(and|or)) (?<name2>\w+)/x){
  say "i saw $+{name} and $+{name2}";
}

&` '{^MATCH} {^PREMATCH}{^POSTMATCH}

  • $&:保存的是整个匹配的字段
  • $`:匹配区段之前的内容
  • $':匹配区段之后的内容
if("hello there,neighbor"=~ /\s(w+),/){
  print "that was ($`)($&)($')";#会拖慢速度
  print "that was (${^PREMATCH})(${MATCH})(${POSTMATCH})"#不会拖慢速度
}
## 匹配内容分别为(hello)( there,)( neighbor)

正则表达式处理文本

  • 替换:s///
    • 全局替换:s///g
    • 不同界定符:s###g s{}{} s[]{}
    • 复制,替换:
my $original="fred ate 1 rib";
(my $cope=$original)=~s/\d+ ribs?/10 ribs/;
my $cope = $original =~s/\d+ ribs?/10 ribs/r;
##上面两种写法均可得到$cope="fred ate 10 ribs";
  • 大小写转换:
    • 所有字符转换为大写:\U
    • 所有字符转换为小写:\L
    • \E关闭大小写功能
    • 影响紧跟其后的第一个字符改变大写和小写:\u \l
    • 首字母大写,后面的均小写
    • 不仅仅匹配,其他位置也可以用
$_="i saw Barney with Fred";
s/(fred|bareny)/\U$1/gi #得到:i saw BARNEY with FRED
s/(fred|bareny)/\L$1/gi #得到:i saw barney with fred 
s/(\w+) with (\w+)/\U$2\E/i #第二个括号匹配不惊醒大写转换
s/(fred|barney)/\u$1/ig # 变为 BARNEY with Fred
s/(fred|barney)/\u\L$1/ig 
my $a="FRED";
my $b="fRed";
if("\L$a" eq "\L$b"){
  print "it matched";
}
  • 元字符批量转义:\Q:会把后续字符串中出现的所有元字符自动转义为本义字符,\E:会标明结束位置
if(s/\(\(\(fred/fred/){}
if(s/\Q((\E(fred/fred/)
#将两个( 转化为本义(,最后一个(不转换为本义

从命令行直接替换文件内容

perl -p -i.bak -w -e "s/Randall/Randal/g" filename
# -p 使perl自动生成一段代码:while(<>){print;}
# i.bak 做备份 不想备份直接-i
# -w 开启警告功能
# -e 会将其后面的内容当做程序代码
  • 功能:匹配数组中元素
my @tmp = ("FRY","LHM","TPJ");
my @con = grep /TPJ|LHM|FRY/i,@tmp;
my $con = @con;
if($con != 0){ 
|___my $aim = "CON::@tmp\n";
|___print "aim:::$aim\n";
}

相关文章

网友评论

      本文标题:2020-03-19 perl 中正则匹配总结

      本文链接:https://www.haomeiwen.com/subject/ztmryhtx.html