侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

浅谈正则速记法的技巧

前端  /  管理员 发布于 7年前   167

给你一篇文章,如何挑选出你想要的字符串呢?你可以从左到右从上到下,一个一个字符读取出来,写一大堆if做判断。这样太麻烦了,正则就是将以上过程抽象出来,用一些特定符号就能表示出大部分规则

对大部分人来说,正则主要是难记,其实只要对正则符号分类记忆,就会发现核心概念其实特别简单

注:本文会假设你至少看过一遍正则的文档,如果没看过,可以看mdn(有中文翻译),如果觉得mdn排版乱,推荐去https://devdocs.io/javascript/global_objects/regexp学习。本文所使用语言为javascript

元字符

/a/中的a就是一个元字符,一个元字符匹配一个实体字符,这里的“a”没有特殊含义,就匹配一个英文a

像/\d/就匹配0到9的所有数字,如果两个连写/\d\d/就可以匹配10到99的所有数字

/./可以匹配任何字符

集合

假如有一串字符串'0123456789',我只想匹配其中的'3','6','9',这时可以放在集合中/[369]/

执行后会发现只有3被匹配到,是因为集合中不管写多少东西都代表一个元字符,集合也是一种元字符
你可能见过这样都集合/[0-9a-zA-Z_]/它代表匹配所有数字,字母和下划线,它与元字符/\w/的效果是一样的,集合更灵活\w更方便

排除型集合

/[^0-9]/除了数字都匹配(我喜欢叫它否定集合)

或(多选)

假设我有一大堆书单,我希望从中匹配出naroto和one piece,那么可以这样写/naroto|one pice/ 竖线代表或,a或b,你也可以写多个a|b|c|d,你当然可以写出0|1|2...|9来匹配所有数字。但要注意和集合的区别,集合是一个元字符,不能匹配单词,|两边可以是多个元字符

分组

我现在有一堆文件,我希望匹配出后缀是.css和.less的文件,你可以很自然的写出/.css|.less/这样的代码。其实还有一个简便写法/.(c|le)ss/,分组可以将若干个元字符放在同一个作用域中做处理,通过分组我们可以写出更简练的代码

分组还有一个特殊的用法,思考如何匹配'asd_asd_asd_asd_asd'这种字符串?

答案是/(asd)(_\1)+/,\1是个非常特殊的元字符,代表重复使用第一个分组的匹配结果,\2就代表第二个,以此类推,+加号表示重复一到多次(这个后面会讲),需要注意的是计数从1开始,\0代表另外的意思(请看文档)

量词

一长串字符中我只想匹配连续的数字,但/\d/只会匹配一个,这时候可以使用量词/\d{n,}/,n写几就是几到多,比如{1,}就是1到多。{n}这种写法表示n个相连,匹配2333可以写成/23{3}/

还有几个简写的量词

  • +代表1到多,等于{1,}
  • *代表0到多,等于{0,}
  • ?代表0或1个,等于{0,1}

贪婪模式和非贪婪模式

量词有个尴尬的地方,比如用/.*a/去匹配 '123a123a',本来希望得到'123a',实际却得到'123a123a'。这是因为任何字符都满足/./加上量词会导致从头匹配到尾,但因为我们还有其他元字符,所以这时正则引擎会回溯,将已经匹配的结果从后往前一个个拿出来,与剩下的元字符相匹配。
这种模式叫贪婪模式,它可能会产生预期之外的结果和不必要的性能浪费

解决方案是使用非贪婪模式,在量词后面加?问号可以得到最小结果,现在使用/.*?a/去匹配就可以得到'123a'了。任何量词后都可以使用非贪婪模式

环视

x(?=y)这个功能有很多种翻译,比如零宽断言,我个人感觉比较准确的是“正向肯定环视”
x(?!y)正向否定环视

x代表元字符,y也代表元字符,x(?=y)的意思是紧接着y的x,比如 '-1a--2b-',使用/\d(?=a)/去匹配,会得到1;/\d(?!a)/去匹配,会得到2。

这功能怎么用?举个例子,有一段字符串'a(123)b',我只想要括号内的内容,但不想要括号
我需要匹配到右括号左边的位置,那么我可以写成/(?=\))/(注意括号需要转义),我不想要左括号/[^(]/,我不关心括号内的内容/.*/,这时组合三个正则就变成了/[^(].*(?=\))/

实际上这个功能匹配的是位置,从匹配到的位置开始找元字符,所以你如果在环视后面加量词是没用的

其他

^和$也是匹配位置的元字符,分别是匹配开头和结尾,比如我们想匹配文件结尾是.js的文件可以写成/.js$/。匹配http开头的链接可以写成/^http:\/\//

还有一些特殊的\u[\b]\0等,需要你自己看文档

标识符

g:一个正则只会匹配一次,如果加上g标识符就会全局匹配, /\d/g,这个正则是不管两个数字之间隔了什么,都会将所有数字匹配出来

i:不区分大小写/^http:\/\//i就会匹配http://和HTTP://

核心概念就这么多,其他内容请详细查看文档

你以为这就结束了?其实还有后续哒!

我要继续说环视

还有个神奇的逆向环视没有讲x(?<=y) ,因为这是18年才进正式标准的功能,虽然它可能比js年龄大,但js就是不支持你怕不怕!

前面那个/[^(].*(?=\))/可以改成/(?<=y).*(?=\))/

正则最大但坑就是,让新手产生正则无所不能的想法,一个复杂字符串处理总以为可以通过一个神奇的正则来搞定。

正则不是万能的!

还是之前的例子,给字符串'a(1\(2(3)'让你取括号内的内容请问你怎么取?首先应该弄清需求,如果正则过于难写,可以用js的字符串处理函数辅助正则,分部操作。另外正则的性能并不高,不是说很复杂的操作写成一行正则性能就比其他方式快了,没有测试就没有发言权

正则理论上是有极限的,举个例子,有字符串1xxxyyyy2让你取{n}个x和{m}个y,n和m是不确定个数,写成x{1,}y{1,}是没问题的,但如果要求是x{n}y{n}就不行了,比如一个字符串有3个x,你就要取3个y,有4个x,你就要取4个y,单靠正则就无法完成了。

正则难,难在门槛高,门槛高在难记,之所以难记,其实还是因为反人类的符号让你下意识的排斥它。熟悉正则,正式正则,学会正则,会给你带来超乎想象的便利!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    解决正则表达式\w和\d的疑惑
    下一条:
    正则表达式实现手机号中间4位数隐藏或者只显示末尾四位数
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 使用 Alpine.js 排序插件对元素进行排序(0个评论)
    • 在js中使用jszip + file-saver实现批量下载OSS文件功能示例(0个评论)
    • 在vue中实现父页面按钮显示子组件中的el-dialog效果(0个评论)
    • 使用mock-server实现模拟接口对接流程步骤(0个评论)
    • vue项目打包程序实现把项目打包成一个exe可执行程序(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-03
    • 2018-04
    • 2018-05
    • 2018-06
    • 2018-09
    • 2018-11
    • 2018-12
    • 2019-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2021-04
    • 2021-05
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客