正则表达式学习笔记

本文详细介绍了正则表达式的基本概念和常用特殊字符,包括非打印字符、限定符(如*、+、?)、定位符(^、$、、B)以及通过转换的特殊字符。还讨论了限定符的贪婪与非贪婪模式,并举例说明了正向预查和反向预查的用法。最后提到了修饰符(如i、g、m、s)对匹配的影响和运算符优先级。
摘要由CSDN通过智能技术生成

前言:每次用到正则表达式都是百度,很不方便,并且测试好多次才能达到想要的效果。正则表达式的规则不难,但是要想用好却不容易,主要还是一个“熟能生巧”。所以专门花一些时间自己动手实现一下常用的正则表达式。主要参考菜鸟教程
正则表达式

  • 正则表达式是什么?
    1、正则表达式(Regular Expression)是一种文本模式,提供字符串匹配规则。正则表达式包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。
    2、特殊字符按用途可以分为两类,一种是用来修饰普通字符的,比如*,必须和普通字符连用才能发挥它的价值;一种是使用\转义为特殊字符的,这种用起来和普通字符是一样的,只不过能匹配上的子串比较多。
  • 正则表达式能做什么?
    1、查找
    2、替换
    3、提取
  • 碎碎念
    正则表达式的难点在于特殊字符的分类使用方面。虽然都是特殊字符,但是通过用法可以分为好几类。在使用的时候需要明确所使用的特殊字符的作用。所以这里将特殊字符根据其用途分为了几类,但其中可能有交集。这里我只研究了本人在前端开发中能用得到的。

一、特殊字符

(一)非打印字符

字符描述
\n匹配换行符。
\r匹配回车符。
\s匹配任何空白字符,包括空格、制表符、换页符等等。
\S匹配任何非空白字符。
\t匹配制表符。就是tab

(二)限定符

限定符需要跟在一个表达式的后面,用于规定匹配前面的表达式的次数

字符描述
*子表达式出现0次或多次
+子表达式出现一次或多次
?子表达式出现零次或一次
{n}n是一个非负整数,出现n次
{n,}n是一个非负整数,至少出现n次
{n,m}nm都是非负整数,并且n<m,出现[n,m]次

重点解析?
?有两种用法

  1. 一种是放在子表达式的后面,表示该子表达式出现零次或一次
  2. 第二种是放在其他的限定符后面,此时匹配规则会变成非贪婪模式。即尽量较少的匹配字符。正则匹配默认是贪婪模式,举个例子看两者的区别:
'apppp'.match(/a[p]+/)  // 贪婪模式,尽可能多的匹配字符
// 输出
['apppp', index: 0, input: 'apppp', groups: undefined]
// --------------------------------------------------------------------------------------------------
'apppp'.match(/a[p]+?/)  // 非贪婪模式,尽可能少的匹配字符
// 输出 
['ap', index: 0, input: 'apppp', groups: undefined]

(三)定位符

定位符用来规定特定位置的匹配规则

字符描述
^匹配字符串开始的位置,后面跟匹配规则,如/^[0-9]/说明以数字开头
$匹配字符串结尾的位置,前面跟匹配规则,如hhh$表示以“hhh”这个字符串结尾
\b匹配字符串的边界,即字符前面或后面有空格,如果是/\bcha/会从字符串开头找;如果是ter\b会从字符串结尾找
\B匹配字符串的非边界,即在字符串中间进行匹配,不可匹配单词的开头和结尾,\B写匹配规则的前面后面都一样
例子:
'chapterdfs'.match(/\bcha/)  => ["cha"] (1)  //在开头找cha子串
// --------------------------------------------------------------------------------------------------
'chapterdfs'.match(/dfs\b/)  => ["dfs"] (1)   //在结尾找dfs子串
// --------------------------------------------------------------------------------------------------
'chapterdfs'.match(/\Bcha/)  => null   //cha子串在边界,所以使用\B找不到
// --------------------------------------------------------------------------------------------------
'chapterdfs'.match(/\Bha/)  => ["ha"] (1)   //在字符串的中间找"ha"

(四)通过 \+英文字母 转换的特殊字符

已经讲过的字符就不再赘述(\n\s\r\s\S\t\b\B)

字符描述
\d匹配数字,等价于[0,9]
\D匹配非数字
\w匹配字母、数字、下划线
\W匹配非字母、数字、下划线

(五)特殊字符的组合技

已经讲过的字符就不再赘述({n}{n,}{n,m})

字符描述
[abc]字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 “plain” 中的 ‘a’。
[^abc]负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 “plain” 中的’p’、‘l’、‘i’、‘n’。
[a-z]字符范围。匹配指定范围内的任意字符。例如, '[a-z]' 可以匹配 ‘a’ 到 ‘z’ 范围内的任意小写字母字符。
[^a-z]负值字符范围。匹配任何不在指定范围内的任意字符。例如,‘[^a-z]’ 可以匹配任何不在 ‘a’ 到 ‘z’ 范围内的任意字符。
x竖线y匹配x或y
()表示里面的内容是一个表达式,类似于数学中的()的作用。

重点解析()

在不使用修饰符的情况下使用match方法,返回的是一个类数组对象

  1. (pattern) 方法
'oko4gyhjgjghj5gh'.match(/([k-o]|jhljil)[1-9]/)
// 输出
(2) ['o4', 'o', index: 2, input: 'oko4gyhjgjghj5gh', groups: undefined]

第一个元素是通过匹配规则的子串,第二个元素是真正起作用的匹配规则;这里[k-o]是匹配从k到o的字母,但真正匹配上的就是o这个字符

  1. (?:pattern)
'oko4gyhjgjghj5gh'.match(/(?:[k-o]|jhljil)[1-9]/)
// 输出
['o4', index: 2, input: 'oko4gyhjgjghj5gh', groups: undefined]

只返回通过匹配规则的子串信息,不返回真正起作用的匹配规则

  1. (?=pattern) 正向肯定预查
    匹配顺序从左向右,用于匹配()前面的子串,即一个子串后面跟的内容符合这个匹配规则,那么就可以找到这个子串
'window7777'.match(/[a-z](?=[0-9])/)     //匹配后面跟数字的字母
// 输出
['w', index: 5, input: 'window7777', groups: undefined]
'windowhhh'.match(/[a-z](?=[0-9])/)
// 输出
null
  1. (?!pattern) 正向否定预查
    匹配规则从左向右,用于匹配一个后面不跟特定内容的子串
'windowhhh'.match(/[a-z](?![0-9])/)   // 匹配后面跟的不是数字的字母
// 输出
['w', index: 0, input: 'windowhhh', groups: undefined]
// --------------------------------------------------------------------------------------------------
'window999'.match(/[a-z](?![a-z])/)   // 匹配后面跟的不是字母的字母
// 输出
['w', index: 5, input: 'window999', groups: undefined]
  1. (?<=pattern) 反向肯定预查
    与正向肯定预查类似,但是方向相反,放在要找的子串的前面,如果一个子串前面的内容可以匹配上规则,那么就可以找到这个子串
'This is an apple.'.match(/(?<=\s)[a-z]+/)  // 匹配前面是空格的字母串
// 输出
['is', index: 5, input: 'This is an apple.', groups: undefined]
  1. (?<!pattern) 反向否定预查
    子串前面的内容不符合规则时可以找到这个子串
'This is an apple.'.match(/(?<!\s)[a-z]+/)   // 匹配前面不是空格的字母串
// 输出
['his', index: 1, input: 'This is an apple.', groups: undefined]

(六)通配符

还有一个漏网之大鱼

字符描述
.匹配除换行符(\n、\r)之外的任何单个字符

二、修饰符

修饰符用于指定额外的匹配策略,对于正则表达式的整体起作用

修饰符描述
iignore - 不区分大小写 将匹配设置为不区分大小写,搜索时不区分大小写: A 和 a 没有区别。
gglobal - 全局匹配 查找所有的匹配项。
mmulti line - 多行匹配
s特殊字符圆点 . 中包含换行符 \n 默认情况下的圆点 . 是匹配除换行符 \n 之外的任何字符,加上 s 修饰符之后, . 中包含换行符 \n。

重点解析
I和g比较简单就不举例子了,重点看ms

  • m
    需要在node环境中测试,浏览器中\n会被识别成普通字符串
'amp\napp'.match(/pp/m) // 多行匹配pp字符串
//输出 \n也会被计数,所以index是5
(1) ['pp', index: 5, input: 'amp
app', groups: undefined]
  • s
    默认.是匹配除了\n、\r之外的任意字符,使用s修饰符后,.会匹配包括\n、\r的所有字符
'\nappmbapp'.match(/.(?=app)/)  // 匹配后面跟app的一个字符
// 输出
(1) ['b', index: 5, input: '
appmbapp', groups: undefined]
// --------------------------------------------------------------------------------------------------
'\nappmbapp'.match(/.(?=app)/s)  // 使`.`能匹配上换行
// 输出
(1) ['
', index: 0, input: '
appmbapp', groups: undefined]

三、运算符优先级

正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似。
相同优先级的从左到右进行运算,不同优先级的运算先高后低。下表从最高到最低说明了各种正则表达式运算符的优先级顺序:

运算符描述
\反斜杠转义符
(), ( ?: ), (?=), []圆括号和方括号
*, +, ?, {n}, {n,}, {n,m}限定符
^, $, \元字符(匹配作为作为普通字符的特殊字符,比如\*匹配*这个字符),普通字符表示位置和顺序
竖线替换运算符,表示"或"操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值