前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >IC入职新同学必备技能手册 - Perl (2) - 正则表达式+文本操作

IC入职新同学必备技能手册 - Perl (2) - 正则表达式+文本操作

作者头像
空白的贝塔
发布2020-06-24 16:42:22
2.3K0
发布2020-06-24 16:42:22
举报
文章被收录于专栏:摸鱼范式摸鱼范式

正则表达式 (regular expression -> regex)

  • 什么是正则表达式?(这个定义问题真的难到我了,以下来自百度)

正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。

  • 正则表达式能用到哪些地方?
    • Perl/Tcl/etc (用于脚本中,对string进行搜索、替换,其表达式语法是通用的,并不因为脚本不同有区别)
    • sed/grep (Linux shell cmd)
    • vim/gvim (用于完成文本查找、替换)
  • 为什么要提到正则表达式
    • 因为Perl只所以被广泛使用,就是因为内建强大的正则表达式功能,配合灵活的语法,轻松完成脚本内文本匹配、搜索、替换等功能。

正则表达式 (regex)难不难?

对于刚刚接触它的同学来说,略不友好,其语法、各种各样的灵活组合,看起来有点像天书。如下举例:

代码语言:javascript
复制
(?!(.*_PADCAL_MASK|.*HBM_MISR_MASK|.*POWER_CTL_MASK|.*RG_CTL_MASK))(.*MASK.*)

有点懵逼,是吧。淡定,我选择了一个复杂度较高的例子。大部分日常使用的正则表达式并没有这么复杂。

强烈推荐下面这个免费的regex tester:它提供了online的regex测试、解析,并且例举了全部的可用语法元素。当我碰到不确定的正则表达式 (regex),我就会来这里去验证。

https://regex101.com/

下面开始举例+学习 (for Perl)

再次说明,只看不试是不行的,把下面的regex表达式copy到上面的Online tester里面试试。

既然regex是用来做文本操作,那么我们先设置一个sample text

代码语言:javascript
复制
# 在Perl中定义一个这样数组,4个元素
my @path_arr = (
 '/home/scratch.john_gpu/gv100',
 '/home/scratch.mike_gpu/ga100',
 '/home/scratch.mike_gpu/lr10',
 '/home/scratch.ema_ate/regression' 
);

问题1: 找到所有含_gpu的元素

代码语言:javascript
复制
foreach my $elem (@path_arr) {
 # foreach大家还记得吧
 if ($elem =~ /_gpu/ ) {
  print "$elem \n";
 }
}
#结果是:
/home/scratch.john_gpu/gv100
/home/scratch.mike_gpu/ga100
/home/scratch.mike_gpu/lr10
  • 这个符号组合 =~ 是什么?
    • =~ 是Perl语言中使用正则表达式去判定“是否命中”
    • 同理,还有一个 !~ ,表示用Regex判定“是否没命中”
  • /_gpu/ 是啥?
    • / / 是正则表达式的边界符,里面的称之为“正则表达式”
    • _gpu 就是一个最简单的正则表达式,因为我想搜索哪个元素带有_gpu,那就直接用明文啦。

问题2:找到所有含_gpu/ga100元素

代码语言:javascript
复制
foreach my $elem (@path_arr) {
 if ($elem =~ /_gpu\/ga100/ ) {
  print "$elem \n";
 }
}
#结果是:
/home/scratch.mike_gpu/ga100
  • 正则表达式是啥?_gpu\/ga100
  • 为毛不直接用 _gpu/ga100
    • 因为你想搜索的符号**/**与regex的边界符冲突,对于这种情况(即被搜索符号与regex的语法元素冲突),使用反斜杠 (back-slash)进行转义(escape-char)。类似换行符\n

问题3:找到符合mike****ga100的元素 (*表示不在乎中间是什么字符)

代码语言:javascript
复制
foreach my $elem (@path_arr) {
 if ($elem =~ /mike.*ga100/ ) {
  print "$elem \n";
 }
}
#结果是:
/home/scratch.mike_gpu/ga100
  • 这是什么-> .*
    • 有没有人想问,1-无穷用哪个?+ 咯
    • 这是一个基础的正则表达式啦,要分开说:
    • . 表示任意单个字符 (无论是数字、字母、标点符号、任意的东西)
    • * 表示约束预期出现的个数,允许0-无穷
    • .* 表示,匹配任意字符且出现任意个数。匹配任意东西。
  • 也许,到此为止,对 .* 还是不理解,那么:
    • /w* 首先,/w表示任意字母,*还是表示任意个数。那么,/w* 表示预期匹配任意个数的字母。
    • /d* /d表示0-9的任意数字,/d*就是预期匹配任意个数的数字啦。
    • /d+ /d表示0-9的任意数字,/d+就是预期匹配至少出现一次的数字啦。

问题4:(变得稍微复杂啦) 找到所有g?100的元素(?定义为任意一个字母),并且将g?100这部分字段提取,并打印出来

代码语言:javascript
复制
foreach my $elem (@path_arr) {
 if ($elem =~ /(g\w100)/ ) {
  print "$1 \n";
 }
}
#结果是:
ga100
gv100
  • \w是啥,还记得吧,表示任意字母。
  • 为啥没*了
    • 因为题目要求只要一个文字呀
  • 这次怎么多了一个括号?
    • 这是关键点,这是Regex的匹配且提取
    • 提取什么?能匹配括号里regex的字段咯。
  • $1是什么?
    • 这是Perl语法,如果if语句中,能够发生匹配成功,则
    1,

    2,$3 ... 存储了每个括号中的匹配字段。

    • 能有$2么?能啊,如果有两个括号,且都匹配成功

问题5:(我们要尝试替换啦) 找到所有g?100的元素,并且将g?100替换成lr10

代码语言:javascript
复制
foreach my $elem (@path_arr) {
 $elem =~ s/g\w100/lr10/ ;
 print "$elem \n" ;
}
#结果是:
 /home/scratch.john_gpu/lr10
 /home/scratch.mike_gpu/lr10
 /home/scratch.mike_gpu/lr10   # 这个出现意外不
 /home/scratch.ema_ate/regression # 这个出现意外不
  • 意外吧,为啥后面两个也出来了?
    • 这个是标准的regex替换表达式,s表示替换操作,/// 是分隔符,分隔出了两段空间。
    • 第一段空间是匹配表达式
    • 第二段空间的意义:如果匹配成功,则将符合匹配的字符串替换成第二段空间的文字
    • 因为 $elem =~ s/g\w100/lr10/ ; 这句话,只是匹配然后替换;如果没有匹配成功,自然不会发生替换。
    • s/// 是啥。

问题6:(再高级一点)找到所有g?100元素,并将原字段替换成大写的。

代码语言:javascript
复制
foreach my $elem (@path_arr) {
 if ($elem =~ /g\w100/) {
  $elem =~ s/(g\w100)/\U$1\E/ ;
  print $elem, "\n" ;
 }
}
#结果是:
 /home/scratch.john_gpu/GV100
 /home/scratch.mike_gpu/GA100
  • print函数没用错,可以用逗号进行字符串拼接
  • s/// 出现啦:
    • 第一段中,为啥有括号,因为我们不光要匹配,还要抽取匹配的字段
    • 第二段,$1好理解吧,\U\E是一个搭配组合,表示中间的字段转换为大写。

问题7:Perl常见的传参变量内容替换套路

这样的代码很常见:传递过来一个变量A,我想对A中的字符串内容进行一些操作(比如替换),但我又不想更改A的内容,那么:

代码语言:javascript
复制
my $A = 'my name is jason' ;
(my $B = $A) =~ s/jason/emma/;
print "A = $A \n";
print "B = $B \n";

#结果是:
A = my name is jason
B = my name is emma

写在最后

本篇内容重在抛砖引玉(cover的内容其实很浅),我墙裂建议学习regex的时候,将更多的尝试和验证放在online regex tester上,实践出真知嘛。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 摸鱼范式 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 正则表达式 (regular expression -> regex)
    • 正则表达式 (regex)难不难?
    • 下面开始举例+学习 (for Perl)
      • 再次说明,只看不试是不行的,把下面的regex表达式copy到上面的Online tester里面试试。
        • 问题1: 找到所有含_gpu的元素
          • 问题2:找到所有含_gpu/ga100元素
            • 问题3:找到符合mike****ga100的元素 (*表示不在乎中间是什么字符)
              • 问题4:(变得稍微复杂啦) 找到所有g?100的元素(?定义为任意一个字母),并且将g?100这部分字段提取,并打印出来
                • 问题5:(我们要尝试替换啦) 找到所有g?100的元素,并且将g?100替换成lr10
                  • 问题6:(再高级一点)找到所有g?100元素,并将原字段替换成大写的。
                    • 问题7:Perl常见的传参变量内容替换套路
                    • 写在最后
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档