正则练习题

原题地址:https://www.zybuluo.com/Zjmainstay/note/709093

正则检测: https://regex101.com

 

1. 分组提取/非捕获组

分组,是正则里一个非常重要的概念,我们需要针对某个区域提取数据,往往需要依赖分组。而分组,其实就是正则里()括住的部分。

(1.1)分组提取

需求:在分组1中匹配meta中author属性的值
源串:
<meta author="Zjmainstay" />
another author="Zjmainstay too"
预期:分组1得到Zjmainstay
正则:"(\w+)\b

(1.2)非捕获组

针对上面的分组,有时候,我们并不需要捕获某个分组的内容,我们可以使用非捕获组(?:表达式),从而不捕获表达式部分内容到分组中。

需求:匹配每行字母个数是偶数个的数据,每行数据不为空,正则不能存在分组1
源串:
a
ab
abc
abcd
预期:
匹配得到 ab 和 abcd,不包含分组1
正则:\b(?:\w{4}|\w{2})\b

2. 单字符或

或条件是正则使用过程中常用的概念,比如,密码由字母或数字组成,这里就用到了或条件,而且,由于字母或数字都是单个字符,因此,可以使用[a-z0-9]这样的单字符或语法实现。 
常犯错误:匹配a或b写成[a|b],此表达式实际上表示a或b或|,在[]内部的|表示其本身,注意区分(a|b)表示a或b的写法。

(2)单字符或

需求:匹配由 A/S/D/F 4个字母(区分大小写)组成的长度为3字符串
源串:
ABC
ASD
ADS
ASF
BBC
A|S
A|D
ASDF
预期:以[]元字符获得3个字母的或集,匹配 ASD/ADS/ASF 3组数据
正则:\b[ASDF]{3}\b

3. 多字符或

相对单字符或条件,多字符或也是很常见的,比如,我们需要匹配http或ftp两个协议头的url,就需要^(http|ftp)://.+$这样的语法来实现。

(3)多字符或

需求:匹配每行数据中以.jpg/.jpeg/.png/.gif结尾的图片名称(含后缀)
源串:
image.jpg
image.jpeg
image.png
image.gif
not_image.txt
not_image.doc
not_image.xls
not_image.ppt
预期:匹配 image.jpg/image.jpeg/image.png/image.gif 4个结果
正则:\b\w*.(?:jpg|jpeg|png|gif)\b

4. 分组引用

前面介绍了分组,那某个分组在我们匹配过程中重复出现,又该如何处理?分组引用恰恰解决这个问题。比如,匹配出现重复单词的一行数据,我们可以这么写(多行模式):/^.*?(\b\S+\b).*?\1.*$/m\1表示引用前面分组1中匹配到的内容,也就是重复的单词内容。

(4)匹配连续相同3次的数字

需求:匹配连续相同3次的数字
源串:
111
121
112
222
预期:匹配 111/222 两组数据
正则:(\d)\1\1

5. 匹配换行数据

“我的正则本来好好的,突然不行了!”这个是很多正则新人遇到的问题,而这个问题,很多时候,就是因为原来正则中的.不能匹配新数据里的换行导致的。这时候,只需要把.改成[\s\S]这样的表达式就可以了。这个表达式表示空格或非空格,也就是任意字符啦。

(5)匹配换行数据

需求:分别使用单行模式和普通模式匹配id="author"的div中数据,div标签不在同一行
源串:
<div id="author">
Zjmainstay
</div>
预期:Zjmainstay
正则1:^\w+\b
正则2:\n(\w+\b)    单行模式s

6. 存在(或)

(6.1)匹配多种或条件的数据,没有特殊限制

需求:匹配每行中包含“作者”或者“读者”的数据
源串:
本文的作者是Zjmainstay
本文有很多读者
读者可以是任何一个地方的人
这里的任何一个地方说明读者也能在国外
什么乱七八糟的推理
你不匹配我,凭什么要我推荐你的博客 www.zjmainstay.cn
预期:匹配
本文的作者是Zjmainstay
本文有很多读者
读者可以是任何一个地方的人
这里的任何一个地方说明读者也能在国外

正则:作者|读者

(6.2)匹配多种或条件的数据,有特殊限制(不使用环视)(环视=前瞻后顾)

需求:匹配每行中“读者”在开头或结尾的数据
源串:
本文作者是Zjmainstay,有很多读者
读者可以是任何一个地方的人
这里的任何一个地方说明读者也能在国外
预期:匹配
本文作者是Zjmainstay,有很多读者
读者可以是任何一个地方的人

正则:^读者|读者$        或者添加u修饰符  \b读者|读者\b

 

(6.3)匹配多种或条件的数据,有特殊限制(使用环视)

需求:匹配每行中“读者”在开头或结尾的数据 
源串:
本文作者是Zjmainstay,有很多读者
读者可以是任何一个地方的人
这里的任何一个地方说明读者也能在国外
预期:匹配
本文作者是Zjmainstay,有很多读者
读者可以是任何一个地方的人

正则:((?<=\b)读者)|(读者(?=\b))/u         ((?<=^)读者)|(读者(?=$))

7. 存在(与)

(7.1)校验密码必须包含字母、数字和特殊字符,6-16位

需求:校验密码必须包含字母、数字和特殊字符,6-16位,假定特殊字符为 -_= 三个字符
源串:
12345
123456
1234561234561234
12345612345612345
a1234
a12345
-1234
-12345
a-123
a-1234
a-1234a-1234a-12
a-1234a-1234a-1234
aaaaa
aaaaaa
-_=-_
-_=-_=
预期:匹配
a-1234
a-1234a-1234a-12

正则:(?=^.{6,16}$)(?=.*\d)(?=.*[a-zA-Z])(?=.*[-_=])^.*
PS:并没有要求特殊字符不能在开头,我这里就不写了

8. 特殊限制(环视否定)

(8.1)使用\d{1,3}匹配1-999的数据,不能以0开头

需求:使用\d{1,3}匹配每行中1-999的数据,不能以0开头
源串:
1
10
100
999
1000
01
001
预期:匹配
1
10
100
999
正则:(?=^[^0])(\d{1,3}$)

 

(8.2)匹配除了span标签外的所有标签

需求:匹配除了<span>内容</span>标签外的所有<tagName>内容</tagName>格式标签
源串:
<div>匹配我</div>
<span>不匹配我</span>
<p>匹配我</p>
<i>匹配我</i>
预期:匹配
<div>匹配我</div>
<p>匹配我</p>
<i>匹配我</i>
正则:<(?!span).*(?<!\/span)>

9. 替换分组使用

(9.1)给源串每个链接加上http://www.zjmainstay.cn前缀

需求:给源串每个链接加上http://www.zjmainstay.cn前缀
源串:
<a id="link-1" href="/regexp-one">正则文章合集(All In One)</a>
<a id="link-2" href="/my-regexp">正则入门教程</a>
<a id="link-3" href="/deep-regexp">正则高级教程</a>
<a id="link-4" href="/regexp-lookaround">正则环视详解</a>
<a id="link-5" href="/php-curl">PHP cURL应用</a>
预期:替换得到
<a id="link-1" href="http://www.zjmainstay.cn/regexp-one">正则文章合集(All In One)</a>
<a id="link-2" href="http://www.zjmainstay.cn/my-regexp">正则入门教程</a>
<a id="link-3" href="http://www.zjmainstay.cn/deep-regexp">正则高级教程</a>
<a id="link-4" href="http://www.zjmainstay.cn/regexp-lookaround">正则环视详解</a>
<a id="link-5" href="http://www.zjmainstay.cn/php-curl">PHP cURL应用</a>
查找:href="(.*)"
替换:str.replace(/href="(.*)"/gm,'http://www.zjmainstay.cn$1')

 

(9.2)将每行数据格式化为一条SQL语句

需求:将每行特定格式数据格式化为SQL语句
源串:
1 2017-04-11 Zjmainstay
2 2017-04-12 Nobody
3 2017-04-13 Somebody
预期:替换得到
INSERT INTO table_log(`id`, `created_at`, `author`) values('1', '2017-04-11', 'Zjmainstay');
INSERT INTO table_log(`id`, `created_at`, `author`) values('2', '2017-04-12', 'Nobody');
INSERT INTO table_log(`id`, `created_at`, `author`) values('3', '2017-04-13', 'Somebody');
查找:([0-9])\s(\d{4}-\d{2}-\d{2})\s(\w+)
替换:
     while(result = regExp.exec(str)){
          console.log("INSERT INTO table_log(`id`, `created_at`, `author`) values('"+$1+"', '"+$2+"', '"+$3+"');")
    }

10. 分组可选

(10.1)分组可选

需求:判断如果单词以A开头,匹配Apple;如果单词以B开头,匹配Banana;否则匹配Empty
源串:
Angle
Apple
Banana
Best
Empty
预期:匹配
Apple
Banana
Empty
正则:^(Apple|Banana|Empty)$

(10.2)分组可选与分组引用

需求:匹配html标签的属性值,属性值可以由双引号、单引号、无单双引号定界
源串:
<div id="I'm Zjmainstay" class="name" data-year=2017 age='27'>
预期:分组匹配
I'm Zjmainstay
author
2017
27
正则:"(.*?)"|=(\d+)|'(\d+)'

11. 单字符拆分(数字)

(11)匹配0.00-100.00的数值,可以有0-2位小数

需求:匹配0.00-100.00的数值,可以有0-2位小数,不能以小数点结尾,不能以2个以上的0开头
思路:(100|10-99|0-9) + 0-2小数位 + 排除小数点结尾、2个以上0开头的情况
源串:
0
1
0.0
0.00
9.00
18.00
27.0
36.00
45.00
54.00
63.00
72.00
81.00
90.00
99.99
100.00
0.
001
100.01
100.001
101
预期:匹配0.00~100.00
正则:(?!^0{2})^\d{1,3}(\.\d{1,2}){0,1}$   (不能排除大于100的情况)

12. 贪婪模式

贪婪模式,正则会优先尽可能多地匹配能匹配到的内容。当剩余正则匹配剩余部分字符(源串)但无法满足匹配时,贪婪部分回溯,吐出已匹配的内容,尝试满足剩余部分字符的匹配。

12.1 匹配链接中的文件名

需求:利用贪婪模式,分组1得到每行链接中的文件名
源串:
http://localhost.com/a/b/c/d/file1.txt
https://localhost.com/a/b/file2long.jpg
预期:分组0匹配行数据,分组1匹配文件名
file1.txt
file2long.jpg
正则:/^(http[s]?:\/\/.*\/(.*))$/gm

12.2限定字符贪婪优化匹配性能

需求:匹配div id="author"的标签内容
源串:
<div id="author" class="author-text something-useless">Zjmainstay</div>
预期:利用贪婪模式去掉div中的噪点(无关数据),分组1匹配到Zjmainstay
正则:/<div[^>]*>([^<]*)<\/div>/gm  |  <div[^>]*>(\w+)

13.非贪婪模式

贪婪模式,正则会优先尽可能少地匹配能匹配到的内容。当剩余正则匹配剩余部分字符(源串)但无法满足匹配时,非贪婪部分继续匹配更多内容,尝试满足剩余部分字符的匹配。

需求:匹配p标签内容
源串:
<p>内容1</p><p>内容2</p>
预期:
在分组1中匹配到内容1和内容2
正则:/<[^>]*?>([^>]*?)<\/[^>]*?>/gm
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值