Perl正则表达式

2. 用正则表达式进行匹配

2.1 用 m// 进行匹配

到目前为止,我们都是讲正则表达式的内容写在一对斜线内,如/fred/。但其实这是 m// 的简写,其中m代表match,和之前看到的 qw// 类似,我么可以自行选择用于保卫内容的一堆字符作为边界,所以上面这个例子可以改写为m{fred},m[fred],m!fred!等。

  • 在不冲突的情况下,建议使用双斜线 // 或 花括号 {}
  • 冲突情况下建议使用其他字符串,如/http:\/\// -> m%http://%

2.2 模式匹配修饰符

正则表达式可以在末尾添加修饰符,这些修饰符有时候也被称作标志。
表2.2 常用模式匹配修饰符

修饰符 规则 举例 解释
i 无关大小写匹配 /yes/i 可以匹配YeS
s 匹配任意字符 /(.)a/s (.)可以匹配任意字符,包括 \n (注意和字符集\s的区别)
x 插入辅助空白字符 / -? [0-9]+/x 可以忽略模式中的空格,如果希望匹配空格可以使用反斜线转义
si 联合使用修饰符 /(.)a/ (.)可以匹配任意字符,同时a字符匹配时忽略大小写(其他组合一是允许的)
a ASCII解释方式 /\w+/a 包括A-Z a-z 0-9 _ 字符
u Unicode解释方式 /\w+/u Unicode中定义为单词的字符
l 类似于ASCII /\w+/l 包含ASCII方式,但单词字符的定义取决于本地设定
n 非捕获分组 /(a)(.*)(b)/n 所有捕获变量都是未定义,$1的值为undef
p 自动捕获变量修饰 /adc(.)/p 只在当前正则表达式中开启自动捕获变量

2.3 锚位

默认情况下,如果字符串的开头不匹配给定模式,就会顺移到下一个字符位置继续尝试。为了让模式只匹配固定位置上的字符我们可以设置模式锚位。
表2.3 常用模式匹配锚位

锚位 举例 说明
\A /\Ahttps?/ \A匹配绝对开头,匹配失败不会顺移
\z /.png\z/ \z匹配绝对末尾,.png后必须没有任何字符,才能成功匹配
\Z /.png\Z/ \Z匹配相对末尾,除\z功能外,如果.png后包含换行符\n,也可以匹配
^ /^narney/m //m的搭配表示匹配行首,m为修饰符;单独的^字符,和\A行为相同
$ /narney$/m /$/m的搭配表示匹配行尾,m为修饰符;单独的$字符,和\z行为相同
\b /\bfred\b/ \b为单词边界锚位,可以匹配任何单词的首位,属于整词匹配
\B /\bfred\B/ \B为\b的取反,可以匹配所有\b不能匹配的位置

2.4 绑定操作符 =~

正则表达式默认的匹配目标是$_,如果要制定匹配某个变量的文本,可以使用绑定操作符(binding operator) =~ ,左侧为变量,右侧为正则表达式。

#!/usr/bin/perlmy $some_other = "I dream of betty rubble.";
if ($some_other =~ /\brub/) {print "Aye, there is the rub.\n";
}
#虽然绑定操作符看起来像是某种赋值操作,但其实并非如此!

2.5 捕获变量

  • 正则表达式中出现的圆括号一般都会触发正则引擎捕捉到匹配的字符串。

    • 捕获组会把匹配括号中模式的字符串保存到相应变量;
    • 如果不止一个括号,也就不只一个捕获组;
    • 每个捕获组存储的是原始字符串中的内容,而不是模式本身,可以反向引用取得这些内容,如(ab)\1。
  • 捕获变量保存的是字符串,它实质上是标量变量。
    • 默认变量名称为$1,$2,其中n代表第几对括号中所捕获的字符串内容。
    • 匹配失败时,$3为空字符串,但是未定义$100的值为undef。

2.5.1 捕获变量的生命周期

捕获变量(如$1,$2)的生命周期是指捕获变量中的值可以保存多久;捕获变量中的内容一般会保持到下次成功匹配为止,即匹配失败的手不会改动上次成功匹配的内容,而成功匹配将会刷新捕获变量中的值。

  • 捕获变量只应该在匹配成功时使用,否则得到的就是上次匹配成功的值,这可能不是我们想要的结果;
  • 由于捕获变量的生命周期较短,当使用捕获变量时只应该在模式匹配成功后的数行内使用;
  • 如果希望在数行之外使用,最好将其复制到某个普通变量中;如my $here = $1;

2.5.2 禁用捕获的括号

  • 目前正则表达式中的括号都会自动捕获匹配的字符擦混,但是有些时候我们希望关闭这个功能;
  • 只是用圆括号来分组,或者是使程序结构清晰,更容易读懂。
  • 禁用捕获的括号(?:acbd)
#!/usr/bin/perl
if (/(bronto)?saurus (stack|burger)/) {print "Fred wants a $2\n";
}
#有时候尽管bronto不存在,仍然需要把$1留给它,perl只看左圆括号(决定捕获变量名称,因此我们只能使用$2来取得我们想要的结果。
if (/(?:bronto)?saurus (stack|burger)/) {print "Fred wants a $1\n";
}
#使用(?:)关闭第一个模式分组的捕获功能,这样我们可以是使用$1来引用第二个分组中的内容;
if (/(bronto)?saurus (stack|burger)/n) {print "Fred wants a $1\n";
}
#使用//n关闭全部正则表达式中的捕获功能,此时$1和$2的值均为undef

2.5.3 命名捕获

  • 有时候,我么不希望使用$1,$2这些意义不明的捕获变量,我们希望自己给捕获变量命名;
  • 可以使用捕获标签,(?<name1>\w+)
    • 当这个模式分组匹配成功后,可以使用$name1取得匹配的字符串。
  • 使用捕获标签后,可以随意移动位置并且加入更多地捕获括号;
  • 使用捕获标签后,标签-匹配字符 作为 key-value对存储哈希 %+ 中,取字符串时应使用哈希的方式 $+{label};
#!/usr/bin/perl
my $name = "fred or barney";
if (/(fred) and (barney)/) {say "I saw $1 and $2";                                     #匹配失败,不打印
}
if (/(fred) (and|or) (barney)/) {say "I saw $1 and $2";                                     #匹配成功,打印 I saw fred and or
}
if (/(?<name1>fred) (and|or) (?<name2>barney)/) {say "I saw $+{name1} and $+{name2}";                       #匹配成功,打印 I saw fred and barney
}
if (/(?P<name1>fred) (and|or) (?P<name2>barney)/) {           #支持python风格的写法say "I saw $+{name1} and $+{name2}";                       #匹配成功,打印 I saw fred and barney
}
my $name = "fred Flint and barney Flint";
if (/fred (?<lastname>\w+) (and|or) barney (\g{lastname})/) {  #使用\g{label}反向引用say "I saw $+{lastname}";                                  #匹配成功,打印 I saw Flint
}
if (/fred (?<lastname>\w+) (and|or) barney (\k<lastname>)/) {  #使用\k<label>反向引用say "I saw $+{lastname}";                                  #匹配成功,打印 I saw Flint
}

2.5.4 自动捕获变量

  • perl提供三个不加捕获括号也能使用的变量,但是为了防止和用户定义名称重复,他们的名字有点诡异。
  • 虽然这三个变量可以免费使用,但是一旦使用自动捕获变量,其他正则表达式的运行速度也会跟着变慢。
    Perl 5.10之后,为了防止自动捕获变量拖慢程序速度,我们可以指定自动捕获变量的作用范围。修饰符/p只针对当前表达式开启自动捕获变量,但是他们的名字不是$` $& $’ 而是作了相应修改,见下表:

表2.5 自动捕获变量及说明

自动捕获变量 使用//p修饰符 说明
$` ${^PREMATCH} 匹配区段之前的内容存储
$& ${^MATCH} 匹配区段的内容存储
$’ ${^POSTMATCH} 匹配区段之后的内容存储
#!/usr/bin/perl
if ("Hello there, neighbor" =~ /\s(\w+),/) {                      #使用自动捕获变量print "That was ($`)($&)($').\n";                             #打印: That was (Hello)( there,)( neighbor).
}
if ("Hello there, neighbor" =~ /\s(\w+),/p) {                     #使用修饰符/p提升程序速度print "That was (${^PREMATCH})(${MATCH})(${^POSTMATCH}).\n";  #打印: That was (Hello)( there,)( neighbor).
}

2.6 regex中的优先级

正则表达式的优先级只有5个级别,见表2.6:
表2.6 正则表达式的优先级(上面优先级高)

正则表达式特性 示例
圆括号 (…) , (?:…), (?<label>…)
量词 a*, a+, a?, a{n,m}
锚位和字符序列 abc, ^, $, \A, \z, \Z
择一选择 a|b, a|b|c
原子 a, [abc], \d, \1, \g{2}
  • 在理解相当复杂的正则表达式时,就得按照perl的优先级按部就班的分析;
  • /\Afred|barney\z/ 表示以fred开头,或者以barney结尾的字符串。
  • 在更复杂的正则表达式中,建议增加圆括号,使得意义清晰。

2.7 模式测试程序

在编写perl程序的时候,每个程序员都避免不了要使用正则表达式,但有时候很难轻易看出一个模式能够做什么,下面这个程序非常实用,可以用于检测某些字符串是否能够被指定模式匹配以及在什么为止匹配,在将正则表达式写入主程序之前,不妨先用以下程序测试一番,检验是否复合预期要求;

#!/usr/bin/perl
#可以用以下程序调试正则表达式,验证是否符合我们期望的匹配结果
while (<>) {chomp;if(/YOUR_PATTERN_GOES_HERE/) {say "Matched: |$`<$&>$'|";         #打印:Matched: |before<match>fafter|} else {say "No match: |$_|";              #打印:No match: |beforematchafter|}
}

Perl正则表达式(2) - 用正则表达式进行匹配相关推荐

  1. 正则表达式学习笔记001--点号匹配

    正则表达式学习笔记001--点号匹配 以前写的课程都没有附上源码,很抱歉! 交流群1:251572072 交流群2:170933152 也可以自己下载: 正则表达式学习笔记001--点号匹配 http ...

  2. js进阶正则表达式10-分组-多行匹配-正则对象的属性(小括号作用:分组,将小括号里面的东西看成一个整体,因为量词只对前一个字符有效)(多行匹配:m)(属性使用:reg.global)...

    js进阶正则表达式10-分组-多行匹配-正则对象的属性(小括号作用:分组,将小括号里面的东西看成一个整体,因为量词只对前一个字符有效)(多行匹配:m)(属性使用:reg.global) 一.总结 1. ...

  3. python正则表达式 多个条件的匹配

    python正则表达式 多个条件的匹配 result = re.search(('大功率.*CIR|标准型.*CIR|小型化.*CIR',i) 通过使用 这些关键字可以实现在正则匹配时对多个字段的匹配

  4. perl基本语法四-正则表达式

    文章目录 1.模式匹配 2.反向引用 3.常用符号 4.锚位 5.绑定操作符~ 6.模式串中的内插 7.捕获变量 1.捕获变量() 2.只分组不捕获(?:) 3.捕获变量命名(?<>) 4 ...

  5. oracle正则表达式包含但不含_正则表达式里字符串”不包含”匹配技巧 - 穿梭于偶然...

    经常我们会遇到想找出不包含某个字符串的文本,程序员最容易想到的是在 事实上,说正则表达式里不支持逆向匹配并不是百分之百的正确.就像这个问题,我们就可以使用否定式查找来模拟出逆向匹配,从而解决我们的问题 ...

  6. 超Easy正则表达式实战教程---入门 :匹配多种形式浮点数

    超Easy正则表达式实战教程-入门 :匹配多种形式浮点数 浮点数多种形式,包括如下: 3.6 , +3.14 , -3.14 , .7 正确匹配上述浮点数,正确姿势如下: ~ [+-]?[0-9]+. ...

  7. php中ip地址的正则表达式,PHP_IP地址正则表达式匹配方法,正则表达式(Regular Expression, - phpStudy...

    IP地址正则表达式匹配方法 正则表达式(Regular Expression,在代码中常简写为regex.regexp或RE)是计算机科学的一个概念.正则表达式使用单个字符串来描述.匹配一系列符合某个 ...

  8. 正则表达式总结,正则表达式匹配不包含某个字符串

    1.匹配a标签及其url: Regex regA = new Regex(@"<a[\s]+[^<>]*href=(?:""|')([^<> ...

  9. 一篇认真的正则入门文章:正则表达式数字和数字范围匹配表达

    文章目录 正则表达式中的数字 \ d用于单个或多个数字 两位数或三位数匹配 正则表达式0-9 正则表达式1到9 正则表达式0到10 正则表达式1到10 正则表达式1到12 正则表达式1到16 正则表达 ...

最新文章

  1. 太慢不能忍!CPU又拿硬盘和网卡开刀了!
  2. centos6.5_64 java 环境变量配置
  3. ML之ME/LF:机器学习中常见模型评估指标/损失函数(LiR损失、L1损失、L2损失、Logistic损失)求梯度/求导、案例应用之详细攻略
  4. 自定义hive url parse函数
  5. ES5-1 发展史、ECMA、编程语言、变量、JS值
  6. 更新Composer依赖报错处理Fatal error: Declaration of Fxp\Composer\AssetPlugin\Repository\AbstractAssetsRe...
  7. 用emacs做笔记_3种用于记笔记的Emacs模式
  8. 算法交流:分享我的一个算法,实现项目需求
  9. python图片表格转excel表格_Python办公自动化 | word 表格转excel
  10. Windows C语言开发环境实践
  11. 超细节的QT设计完整界面布局的流程-新手向
  12. 在C语言中系统将stdin,咨询关于c语言中getc(stdin)。怎么办?
  13. 第3章第32节:图形的应用:使用图形表达并列关系的内容 [PowerPoint精美幻灯片实战教程]
  14. sql服务器状态已停止,SQL SERVER 2008 SSMS - SQL Server Management Studio 已停止工作
  15. 使用python批量统计小说字数
  16. 计算机关机桌面就还原,电脑重启后桌面还原怎么办
  17. recall和precise的区别
  18. Benchmark Factory 使用 简介
  19. 3-8 导入商品类别数据
  20. 信息系统开发与管理【五】之 系统分析

热门文章

  1. 200套web前端期末大作业 HTML+CSS+JavaScript网页设计实例 企业网站制作
  2. Tomcat 配置用户认证服务供C#客户端调用
  3. 糖尿病治疗进入肽时代,Bachem公司的肽了解一下
  4. ADV流速仪坐标系统
  5. k8s之简单部署java应用
  6. 西门子S7-1500教学视频
  7. EF IN 查询等效语句
  8. 【对讲机的那点事】手置频麻烦?通过ADMS-7给YAESU FTM-400D写频
  9. 护卫神mysql无法启动_护卫神·故障应急排查
  10. 下载 电子商城类型htm模板_【精品素材】 3C数码科技手机产品首页装修psd模板PC端店铺首页设计素材_高清psd图片素材 1920*5054像素...