导图社区 第3章 正则表达式的特性与流派概览
第3章 正则表达式的特性与流派概览 思维导图
编辑于2020-10-21 16:38:48第3章 正则表达式的特性与流派概览
1、在正则的世界中漫步
最早的正则工具ed
ed里有一条指令“Global Regular Expression Print”(应用正则表达式的全局输出)
由于该指令的强大,最后演变为了独立的工具grep,后来扩展为egrep
grep工具
1、支持的元字符有限
2、不断发展,加入新的特性,但是星号或其他量词仍然无法作用于括号内部的表达式
egrep工具
1、极大的发展了grep
2、但还是不够完美
其他工具:awk、lex、sed
由于工具的种类繁多,导致标准不统一
POSIX--标准化尝试
结果
Perl的发展历程
1、开创:Perl作为一个通用脚本语言提供了专用工具sed和awk才能提供的正则表达式
流派的部分整合
1、Perl5契合了互联网革命的节拍,Perl的初衷就是处理文本,而Web页面的生成就是文本处理的
各种工具的初次印象
2、正则表达式的注意事项和处理方式
程序设计语言有3种处理正则表达式的方式
1、集成式
正则表达式是字节内建在语言之中的,例如:perl
2、程序式
3、面向对象式
正则表达式不属于语言的低级语法,相反,普通函数节接受普通字符串,把他们作为正则表达式进行处理,然后由不同的进行不同的关系到一个或多个正则表达式的操作
集成式
1、优点:减轻了程序员的负担,因为它隐藏了一些工作,例如正则表达式的预处理、准备匹配、应用正则表达式、返回结果
程序式和面向对象式
1、Java中正则处理
正常的声明Pattern对象的方式
函数式处理,不需要声明正则表达式对象的便捷函数
2、VB与NET语言的正则处理
1、VB下的处理
2、NET语言的处理
3、PHP的正则处理
4、Python的正则处理
查找和替换功能
引言:“Subject”的例子太简单还不足以说明三种方法的而差异,在本节我们将看到更复杂的例子,进一步解释了不同处理方式在设计方式上的差异
首先给出Perl的例子
Java中的查找和替换
VB.NET中的查找和替换
PHP中的查找和替换
其他语言中的查找和替换
3、字符串、字符编码和匹配模式
作为正则表达式的字符串
关于字符串文字的若干例子
Java中的字符串
字符串由双引号标注,反斜线是元字符,支持各种常见的字符组合\t、\n、\\,因此在字符串作为正则表达式时,需要提供转义字符将Java字符串中支持的元字符,转义为正则表达式中的字符使用;
java字符串中出现未获支持的反斜线转以序列会出错
VB.NET中的字符串
同样由双引号标注,不过该字符串只能识别一个元字符;两个连续的双引号代表字符串中的双引号
C#的字符串
1C#支持两种字符串
1、常见的双引号字符串,只是用" "
2、原生字符串,形式为@" "
无法识别反斜线序列
PHP字符串
1、也提供两种字符串
1、双引号字符串:出现不能明确识别的特殊字符的反斜线序列时,该序列会原封不动的从字符串中传过来,PHP字符串能够识别\t,不识别\w
2、单引号字符串:\'表示单引号,\\表示反斜线;任何其他字符都不会被识别为特殊字符
Pythoin字符串
1、提供好几种字符串文字
1、单引号、双引号字符串与PHP没啥太大区别
2、三重引号的字符串:使用'''作为三重引号;可以包含未转以的换行符
字符编码
相关概念
1、作用:规定不同数值的字节该如何解释
2、不同的编码下,相同的数值的字节可能代表不同字符
3、为什么研究这个字符编码
1、主要是如果我们期望某种特定编码的数据被匹配,程序是否会这样做呢
编码的支持程度
字符还是组合字符序列
1、在Unicode中基本字符分为两种
1、普通字符,对应一个代码点
2、组合字符,对应两个以上的代码点
2、引出问题
1、问题:此时点号匹配的是单个代码点还是这个组合字符呢?
用多个代码点表示同一个字符
1、即同一个字符可能几种代码点组合的表达方式
2、问题:可能导致在匹配的时候,需要指定该字符的所有可能
Unicode3.1+ 和U+FFFF之后的代码点
1、早期的Unicode的代码点格式为:U+FFFF
2、后面扩展了代码点的数量到:U+1FFFF
3、大多数程序的\uXXXX仅支持最多4位十六进制
4、同时也提供了\x{...}能够匹配任意多位16进制
Unicode中的行终止符
正则模式和匹配模式(只看看大多数系统提供的常见模式)
所有模式的功能就是修改或添加匹配规则
不区分大小写的匹配模式--/i
1、作用:在匹配过程中会忽视字母的大小写
2、与Unicode字符集存在特殊问题
宽松排列和注释模式--/x
1、作用:此模式会忽略字符组外部的所有空白字符,字符组内部的空白字符仍然有效,#符号和换行符之间的内容视为注释
点号通配模式(单行模式)--/s
1、作用:
即此时的点号可以匹配换行符
增强的行锚点模式(多行模式)--/m
1、作用:
文字文本模式--\Q...\E
1、作用:
全局匹配模式--/g
4、常用的元字符和特性
字符表示法(用来清晰简洁的匹配难以描述的某些字符)
字符缩略表示法:\n、\t、\a、\b、\e、\f、\r、\v
比较特殊的是\r、\n在不同的平台下,对应了不同的ASCII字符;因此使用时需要格外小心
还有一个就是\b在字符组内外有不同含义
八进制转以:\num
十六进制/Unicode转以:\xnum、\x{num}、\unum、\Unum
控制字符:\cchar
1、许多流派中可以使用控制字符来匹配编码值小于32的控制符
例如:\cH可以用来匹配ASCII的退格符,\cJ可以用来匹配ASCII的换行符
当然,换行符还可以通过字符缩略\n来匹配,还可以通过八进制转以\012,还包括十六进制和Unicode转以的方式
字符组以及相关结构(在正则表达式的某个位置指定一组字符)
普通字符组和排除型字符组:[a-z]和[^a-z]
理解:范围表示法、字符组内外的元符号、肯定匹配一个字符
几乎匹配任何字符的元字符:点号.
理解:点号通常不匹配换行符、匹配模式可以改变点号的匹配规则、java中regex包点号u不能够匹配Unicode行终止符号
单个字节:\C
理解:只有Perl和PCRE支持用\C匹配单个字节
该功能比较危险
Unicode组合字符序列:\X
字符组缩略表示法:\w、\d、\s、\W、\D、\S
注意:此时的大写表示对小写的否定
\d匹配所有的Unicode数字,\w匹配所有单词中的'字符',\s匹配空白字符
Unicode属性、区块和分类:\p{Prop}、\P{Prop}
unicode定义了每个字符的性质,可以根据性质来进行匹配,\p{Prop}、\P{Prop}用来匹配属于和不属于该属性的Unicode字符
普通属性:分类
子属性
属性的使用,可以使用全名或许缩写的单个字符,某些系统单字母属性名可能不需要花括号,有的系统甚至要求使用In和Is前缀
每个普通属性又可以分为具体的子属性
字母表
有的系统能够按照子目标的名字来进行匹配
例如:\p{Hebrew}用来匹配所有属于希伯来文独有的字符
字母表是基于语言的,不会包括特定的书写系统中的所有字符,只包括该语言的独属于的字符
区块
区块类似字母表,区块是Unicod字符映射表中的一定范围内的代码点
字符组运算符:[[a-z]&&[^aeiou]
Java的regex包支持字符组的完整集合运算
OR运算
允许以字符组的方式往字符组添加字符
AND运算
对两个集合进行概念上的与运算,只保留同时属于两个字符组的字符,写法用&&
减法运算
利用AND运算和排除字符组
[...&&[^...]]
POSIX“字符组”方括号表示法:{[:alpha:]}
因此:POSIX字符组就是Unicode的属性原型,使用方法[Posix字符组]
而Posix字符组形式:[:属性:]
POSIX“collating序列”方括号表示法:[[.span-ll.]]
collatin序列会把多个实体字符序列映射到单个逻辑字符中
spal-ll将ll视为一个字符
使用方法:[[.collating序列.]]
POSIX "字符等价类” 方括号表示法:[[=n=]]
字符等价类表示某些字符在排序之类的操作前视为等价的
例如等价类n代表n其余字符
锚点以及其他“零长度断言”(并不会匹配实际文本,而是寻找文本的位置)
行/字符串起点:^、\A
^通常用于匹配文本的起始位置,如果使用了增强的行锚点模式,它就匹配每个换行符之后的位置
\A只能匹配待搜索文本的起始位置
行/字符串终点:$、\Z、\z
本次匹配的开始位置: \G
举例:Perl中的s/.../.../g
作用:帮助迭代匹配
Perl中的/G有三点值得注意
1、指向的位置是每个目标字符串的属性,而不是正则表达式的属性,意味着即使这个正则表达式不用了,该位置依然存在,且可以提供给下一个正则表达式使用
2、 Perl有一个选项,可以使得匹配失败后,不要重新设定/G
3、/G对应的属性可以用于正则表达式无关的结构来检查和修改
之前匹配的结束位置,还是当前匹配的开始位置
前者匹配上一次匹配时结束的位置
后者:在匹配成功后,有传动装置进行驱动,位置会向前移动
单词分界符:\b、\B、\<、\>、....
顺序环视:(?=...)、(?!...);逆序环视(?>=...)、(?>!...)
大多数实现方式都限制了逆序环视中的表达式的长度
一级:只能匹配固定长度的文本(Perl和Python)
二级:支持逆序环视中出现不同长度的多选分支
三级:支持匹配任意长度的文本,但是不能为无限长
注释和模式修饰词(切换使用的正则表达式模式和匹配模式)
模式修饰词:(?modifier),例如(?i)和(?-i)
模式作用范围:(?modifier:...)
注释:(?#...)和#...
文本文字范围:\Q...\E
分组、捕获、条件判断和控制
捕获/分组括号:(...)、\1、\2、...
仅用于分组的括号:(?:...)
命名捕获:(?<Name>...)
固化分组:(?>...)
多选结构:...|...|...
条件判断:(? if then|else)
匹配优先量词:*,+,?,{num,num}
尽可能满足上限
忽略优先量词:*?,+?,??,{num,num}?
满足下限
占有优先量词:*+,++,?+,{num,num}+