当前位置:网站首页>正则表达式
正则表达式
2022-07-03 12:22:00 【Jiutwo】
正则表达式校验工具:https://regex101.com/
基本字符
[] :用于自定义范围集,可指定字符、字符区间、或固定范围集
| 表达式 | 描述 |
|---|---|
[abc] | 任意范围字符集。匹配集合中所含的任意单个字符。 |
[^abc] | 排除范围字符集。匹配任何不在集合中的字符。 |
[a-z] | 字符范围。匹配指定范围内的任意单个字符。 |
. | 匹配除换行符以外的任何单个字符,包括本身。 |
\ | 转义字符。用于表示特殊字符,如:^-[]$/ 等字符 |
\w | 匹配任何字母、数字、下划线中的任意单个字符(等价于[A-Za-z0-9_])。 |
\W | \W 表示\w之外的字符,等价于[^A-Za-z0-9_])。 |
\d | 数字。匹配0-9任何数字。 |
\D | 非数字。匹配任何非数字字符。 |
\s | 空白。匹配任何空白字符,包括空格、制表符、换行。 |
\S | 非空白字符。匹配任何非空白字符。 |
多个字符集可以组合在一起,形成一个更大的字符集,如:[\d\s]
逻辑控制符
在正则表达式中也有逻辑计算符,例如正则 Hi ,表示第一个字符等于H并且第二个字符等于i,它们是默认的&&计算。如果要表达或的关系,就在中间加一个| ,如H|i表示等于H或等于i。
正则中的逻辑控制符只有以下三组:
| 逻辑符 | 描述 |
|---|---|
| ` | ` 或 |
() 子表达示 | 用于独立计算括号中的内容,支持嵌套。如:`(张 |
{} 数量控制 | 对字符或字表达的数量范围进行限定。如:张.{1,3} 表示“张”后面只能跟1到3个任意字符。 |
注意:正则中不存在异或( ^ )逻辑
说明:| 在类Unix系统中使用问题
由于
|在类Unix系统中是特殊字符,当你使用grep或vim进行正则搜索时,必须进行转义。在类Unix系统使用正则搜索正确姿势是:# grep 使用正则 grep '401\|403\|404\|500' nginx.access.log # 在vim 中输入/ 开始正则搜索,同样|需要转义 /401\|403\|404\|500
子表达式
子表达示支持嵌套,如:(www|mvn|test-(bj|sz|gz|sh)).coderead.cn 表示 test子域名又可继续拆分为test-bj、test-sz、test-sh、test-gz。
子表达示也可用于分组引用。
数量控制
量词:即正则表达式中用于范围控制的符号,如 * + ? {m}
数量控制作用于字符或子表达示,已限制其数量范围。\d{6}表示必须是6位数字。请注意:一个{}仅作用于其前面的单个字符如:hi{2} 表示hii,而不是hihi。
量词 * + ? 实际就是对使用 {} 进行数量控制的一个简写
| 表达式 | 描述 |
|---|---|
? | 匹配前面的表达式0个或1个。即表示可选项。相当于{0,1} |
+ | 匹配前面的表达式至少1个。 |
* | 匹配前面的表达式0个或多个。 |
{m} | 匹配前面的表达式m个。 |
{m,} | 匹配前面的表达式最少m个。 |
{m,n} | 匹配前面的表达式最少m个,最多n个。 |
Q:如何限制文本的长度范围?
A:例如限制密码的长度为6~20位:^.{6,20}$
注意:? 用于量词后面可以表示最少化匹配的意思(懒惰匹配)
下面举例说明 ? 的使用场景,下文中包括几对<span></span>标签?
<span>hello</span> <span>uncle</span>
按照一般的思维肯定是两对<span>标签,但是实际上有3对,因为对于整个文本来说还有一对 <span>hello...uncle</span> 。
如图所示,如果使用正则表达式 <span>.*<span> 匹配<span>标签,那么将会匹配到最大的<span>hello...uncle</span>标签,而不是像预期的那样匹配到两个小的/标签。

这时候就可以在量词后面加 ?,告诉正则表达式引擎按最少化匹配。
<span>.*?</span> 和 <span>.*</span> 的区别可以这样理解,两个正则都是以 <span> 开头,中间为任何内容,直到遇到</span>。但.*非常“勤奋”,就算遇到了一个</span>,还会继续向后查看是否还有,后面又找到了一个,就以最后找到的为准。而.*?就比较“懒惰”,遇到第一个</span>就直接匹配为一对<span>标签,然后就去查找下一对 <span> 标签了。
分组、引用和替换
| 表达式 | 描述 |
|---|---|
(expression) | 分组。匹配括号里的整个表达式。 |
(?:expression) | 非捕获分组。匹配括号里的整个字符串但不获取匹配结果,拿不到分组引用。 |
\num | 对前面所匹配分组的引用。比如(\d)\1可以匹配两个相同的数字,(Code)(Sheep)\1\2则可以匹配CodeSheepCodeSheep。 |
$组号 | 替换。替换操作指将正则匹配到的内容,替换成指定字符串,该字符串可通过$组号引用组进行拼装。通过$0可以引用整个匹配的内容。($0在 Python与Javascript中不支持,使用$&代替) |
说明:
- [] 和 () 的一个需要注意的区别是 [] 只能匹配单个字符,而 () 可以匹配多个字符。
[abc] 匹配 a 和 b 和 c
(abc) 匹配 abc
分组
分组指将匹配的内容,使用( )划分成多个组块,分好的组可用于提取、反向引用以及替换操作。

举例1:在 javascript 中使用分组
// javascript
"小丽生日是2011-11-23".match(/(\d{
4})-(\d{
2})-(\d{
2})/);
// 得出结果如下:
['2011-11-23', '2011', '11', '23']
// 一对括号表示一个分组,从1开始计数
移除分组
()即用于子表达示,同时也是一个分组。如果只想用作子表达示,而不想用于分组就可以使用(?: )从分组列表中移除。比如(?:\d{4})-(\d{2})-(\d{2}) 该表达示只存在两个组,月$1和日$2。
嵌套分组
在嵌套分组中组号是如何命名的呢?比如:生日((\d{4})-(\d{2})(\d{2})) 其组号的命名顺序是以开括号出现顺序为准。

分组+量词
同一个分组如果使用了量词,该分组会代表多个值,这时通过$组号去提取值的时候会得到该组最后匹配的值。如 (\d)+ 匹配12345,通过 $1 将得到 5
反向引用
反向引用:指在表达示中通过\组号引用之前的分组,但是不能够引用之后的内容。

举例2:在正则中引用分组,匹配html中的所有标题内容
文本内容如下
<h1>一级标题</h1>
<h2>二级标题</h2>
如果不使用分组,可以按照如下方式匹配,但是这样非常繁琐。
<h1>.*?<\/h1>|<h2>.*?<\/h2>
通过反向引用可以简化正则表达式
<(h[1-2])>.*?<\/\1>

引用替换
引用替换:正则有着强大的替换能力,比如匹配文本中所有空行,然后替换为空(删除);或者匹配所有的注释,然后替换为空;或者匹配普通文本中的所有http链接,然后替换为<a>标签;或者将文本替换为 insert sql 语句。 
举例3:将下文中所有日期替换成yyyy-MM-dd 格式
实现替换的步骤如下:
- 写出匹配日期的正则:
\d{4}[-.\/]\d{2}[-.\/]\d{2} - 对日期年、月、日进行分组:
(\d{4})[-.\/](\d{2})[-.\/](\d{2}) - 在替换字符中引用分组:
$1-$2-$3

替换后的结果

大小写转化
在Idea、VS Code、Sublime、Notepad++等工具进行替换操作时,还可以使用下表中操作符进行大小写转换,但是在编程语言中是不支持的。
| 操作符 | 描述 |
|---|---|
| \u 单个转大写 | 转换下一个字符为大写 |
| \U 全部转大写 | 转换\U后所有字符转大写 |
| \U…\E 区间转大写 | \U与\E区间的内容转大写 |
| \l 单个转小写 | 转换一下个字符为小写 |
| \L 全部转小写 | 转换\L后所有字符转小写 |
| \L…\E 区间转小写 | \L与\U区间的内容转小写 |
具体使用方法是:在替换字符串中加入转换操作符。
举例:把单词首字母转成大写
- 编写匹配正则:
\w+ - 首字母转大写并替换:
\u$0

转换后的结果为:Hello World!
边界断言
边界断言:指一段表达示前后是否满足指定条件,该条件由一个子表达式组成,基于前后字符能否匹配来计算布尔值。因断言部分不会消耗匹配字符,固又称为零宽断言。
边界断言让正则有了条件判断的能力,功能更加强大。
特殊边界断言
| 表达式 | 描述 |
|---|---|
^ | 匹配断言文本或行开头。 |
$ | 匹配断言文本或行结尾。 |
\b | 匹配断言单词的开头或结尾。比如Sheep\b可以匹配CodeSheep末尾的Sheep,不能匹配CodeSheepCode中的Sheep。 |
\B | 匹配非单词边界或结尾。比如Code\B可以匹配HelloCodeSheep中的Code,不能匹配HelloCode中的Code。 |
\A 文本开头 | 断言文本开头。JavaScript 不支持 |
\Z 文本结尾 | 断言文本结尾。JavaScript 不支持 |
说明:
^和$配合边界/m使用表示每一行的开头和结尾,否则表示的是整个文本的开头和结尾。被m修饰后,^表示行的开头,等价于(?<=\n|\A),被m修饰后,$表示行的结尾,等价于(?=\n|\Z)。\b单词边界本质上还是一个边界断言,符合边界断言的特性。\b断言单词的前后是一个\W字符,或是一个其它边界(行边界,文本边界)\bhello\b 等价于 (?<=^|\W|\A)Hello(?=$|\W|\Z)
边界断言语法
| 表达式 | 描述 |
|---|---|
(?=) | 前置断言,判定一段表达式前面是否满足条件。比如Code(?=Sheep)能匹配CodeSheep中的Code,但不能匹配CodePig中的Code。 |
(?!) | 前置否定断言,判定一段表达式前面是否不满足条件。比如Code(?!Sheep)不能匹配CodeSheep中的Code,但能匹配CodePig中的Code。 |
(?<=) | 后置断言,判定一段表达式后面是否满足条件。比如(?<=Code)Sheep能匹配CodeSheep中的Sheep,但不能匹配ReadSheep中的Sheep。 |
(?<!) | 后置否定断言,判定一段表达示后面是否不满足条件。比如(?<!Code)Sheep不能匹配CodeSheep中的Sheep,但能匹配ReadSheep中的Sheep。 |
说明:所谓前置后置是以表达式为中心,边界断言位于表达式的前面(左边)和后面(右边)
例如:
(?<=身高)\d{3}(?=cm)中(?<=身高)为后置断言(表达式后面),(?=cm)为前置断言。
注意:后置断言在javascript中只有部分浏览器支持。另外后置断言非常消耗性能,所以不推荐使用无限大的量词如:*+{n,}。甚至在JAVA、Python、PHP会直接报语法错误。
高级特性
- 零宽断言:断言条件本身不会消耗字符
- **多边界断言:**一个正则可同时存在多个边界断言。根据其所处位置来决定断言的边界。
- 条件组合:多个子断言可以进行布尔运算如:
&&||(), - 任意边界:可以是任意合法的表达式边界,甚至可以是空字符边界。
高级特性之条件组合
边界条件本质上就是布尔值计算,其自然可以进行类似&&||()布尔运算,以应对更复杂的场景。其书写方式有以几种:
h(?=条件1)(?=条件2)且运算,指必须同时满足多个条件h(?=(?=条件1)(?=条件2))且运算,条件1与条件2组成一个新条件,并且两个条件都必须满足h(?=(?=条件1)|(?!条件2))或运算,满足条件1或者 不满足 条件2h(?=表达式1|(?=条件1)(?!条件2))混合运算,表示满足表达式1或者同时满足条件1、2
上述条件组合在后置断言中同样适用,而且没有额外的兼容性问题。另外上述任意条件都是基于同一个边界进行计算,即字符h
修饰符
修饰符用于影响表达式的匹配逻辑。
| 表达式 | 描述 |
|---|---|
/.../i | 忽略大小写。(… 表示正则表达式) |
/.../g | 全局匹配。默认只会匹配一个结果,加上 g 后会匹配全部可匹配结果 |
/.../m | 行边界修饰符。用于多行匹配。 |
/.../s | 使用此修饰符后 . 能匹配任意字符,包括换行符。 |
/.../x | 书写正则表达式时会忽略空白字符,可以多行书写,并可以使用#进行注释说明。JavaScript 不支持 |
对
/m的理解:它的作用是于定义^与$边界断言的作用范围。默认情况下^$分别表示文本的开头与结尾,加上之后表示行首与行尾,也包括文本开头与结尾。一般的正则表达式应用都会加上m修饰符。
在使用类似idea,vs code,或notepad++等工具时,其正则都添加了gmi三个修饰符,而且除了i大小写勿略,其它都不可以改变。
常用正则表达式示例
详情参考
参考资料
边栏推荐
- Attack and defense world mobile--ph0en1x-100
- 【习题七】【数据库原理】
- 剑指 Offer 14- II. 剪绳子 II
- (latest version) WiFi distribution multi format + installation framework
- 【综合题】【数据库原理】
- context. Getexternalfilesdir() is compared with the returned path
- 【習題五】【數據庫原理】
- [review questions of database principles]
- Swift return type is a function of function
- How to convert a decimal number to binary in swift
猜你喜欢

The latest version of lottery blind box operation version
![[problem exploration and solution of one or more filters or listeners failing to start]](/img/82/e7730d289c4c1c4800b520c58d975a.jpg)
[problem exploration and solution of one or more filters or listeners failing to start]
![[data mining review questions]](/img/96/00f866135e06c4cc0d765c6e499b29.png)
[data mining review questions]

Application of ncnn neural network computing framework in orange school orangepi 3 lts development board

The latest version of blind box mall thinkphp+uniapp

电压环对 PFC 系统性能影响分析

Glide question you cannot start a load for a destroyed activity

ncnn神经网络计算框架在香橙派OrangePi 3 LTS开发板中的使用介绍

并网-低电压穿越与孤岛并存分析

Four problems and isolation level of MySQL concurrency
随机推荐
剑指 Offer 15. 二进制中1的个数
2022-01-27 redis cluster cluster proxy predixy analysis
Ali & ant self developed IDE
电压环对 PFC 系统性能影响分析
有限状态机FSM
对业务的一些思考
Dojo tutorials:getting started with deferrals source code and example execution summary
SLF4J 日志门面
[review questions of database principles]
[problem exploration and solution of one or more filters or listeners failing to start]
2022-01-27 redis cluster brain crack problem analysis
[ArcGIS user defined script tool] vector file generates expanded rectangular face elements
Brief introduction to mvcc
Glide question you cannot start a load for a destroyed activity
社交社区论坛APP超高颜值UI界面
sitesCMS v3.0.2发布,升级JFinal等依赖
ORM use of node -serialize
【习题五】【数据库原理】
Nodejs+express+mysql realizes login function (including verification code)
Enable SASL authentication for memcached