正则表达式

在这里插入图片描述

流光容易把人抛
人间朝暮
慢慢散步
-------写下便是永恒

一、正则表达式匹配攻略

正则是匹配模式:
要么匹配字符
要么匹配位置

1.1 两种模式匹配

为什么是模糊匹配,因为如果正则是精准匹配,那么将没有任何意义

/hello/.test(‘hello’);// 只能匹配 hello 字符串,还有什么意义

模糊匹配分为两个方向:横向模糊和纵向模糊

1.1.1横向模糊匹配

就是一个正则可匹配的字符串长度不是固定的,可以是多种情况的。实现方式是使用量词。

如:{m,n} 表示连续出现最少 m 次 最多 n 次

const regex = /ab{2,5}c/g;
const string = 'abc abbc abbbc abbbbc abbbbbc abbbbbbc';
string.match(regex);// ... 这里打印什么

案例中的 g 是一个正则的修饰符。表示全局匹配,即在目标字符串中按顺序找到满足匹配模式的所有字符串,强调的是 ‘所有’,而不是第一个。g 是单词 global 的缩写。

1.1.2纵向模糊匹配

指一个正则匹配的字符串,具体到某一位字符时,它可以不是某个确定的字符,可以有多种可能。

[123] 表示该字符可以是 1 2 3 中的任意一个

const regex = /a[123]b/g;
const str = 'a0b a1b a2b a3b a12b a23b';
str.match(regex)//

1.2字符组

虽然叫做字符组,但是只匹配其中的一个。

比如 [123] 只匹配 1 2 3 其中之一

1.2.1范围表示法

如果字符组里面字符特别多可以使用范围表示法。
[12345abcdeABCDE] 可以写成 [1-5a-eA-E] 使用连接符来省略和简写
连接符 - 有特殊的作用。
那么思考一下要匹配 ‘a’ ‘-’ ‘z’ 怎么处理?
[a-z] 肯定是不对的,这个表达式表示小写字符中的任意一个。

// [-az]或[az-]或[a-z] (可以放开头、结尾或转译,不让引擎认为是范围表示法就可以)

1.2.2排除字符组

纵向模糊匹配,还有一种情形就是,某位字符串可以是除了 a b c 之外的任意字符。这时就是排除字符组的概念。[^abc],表示是一个除了 a b c 之外的任意一个字符。字符组的第一位放 ^(脱字符),表示求反的概念。

1.2.3常见的简写形式

在了解过字符组的概念之后,一些常见的符号也就理解了。他们都是正则中自带的简写形式。

字符组概念
\d数字
\D非数字
\w数字,字母,下划线 [0-9a-zA-Z]
\D非数字
\W\w 取反
\s表示 [ \t\v\n\r\f]。表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页 符。记忆方式:s 是 space 的首字母,空白符的单词是 white space
\S表示 [^ \t\v\n\r\f]。 \s 取反
\n换行
.表示 [^\n\r\u2028\u2029]。通配符,表示几乎任意字符。换行符、回车符、行分隔符和段分隔符 除外。记忆方式:想想省略号 … 中的每个点,都可以理解成占位符,表示任何类似的东西

思考一下,如果要匹配任意字符怎么写?

[\d\D] [\w\W] [\s\S] [^]

1.3量词

量词就是数量的意思,也称重复。上面讲了 {m,n} 的含义,这里要记一些简写形式

1.3.1量词的简写形式

量词概念
{m,}表示至少出现 m 次
{m}等价{m,m} ,表示出现 m 次
?等价 {0,1} 表示出现或不出现记忆方式:问号的意思表示,有吗?
+等价{1,} 表示至少出现一次记忆方式:加号表示追加的意思,得先有一个,然后才能追加。
*等价 {0,} 表示出现任意次,也可能不出现记忆方式:天上的星星,可能一颗都没有,可能几颗,可能多的数不过来
// 看一个正则,解读一下
const regex = /a{1,2}b{3,}c{4}d?e+f*/;

1.3.2贪婪匹配与惰性匹配

const regex = /\d{2,5}/g;
const str = '123 1234 12345 123456 1234567';
str.match(regex);// 6个

正则表示数字连续出现 2 到 5 次。

但是其是贪婪的,他会尽可能多的匹配。能匹配到多少就匹配多少。

而惰性匹配,就是尽可能少的匹配:

const regex = /\d{2,5}?/g;
const str = '123 1234 12345 123456 1234567';
str.match(regex);// 11个

这里的正则表示,2 到 5 个都可以匹配。但是当 2 个就够的时候,就不再往下尝试了。

通过在量词后买你加问好就能实现惰性匹配,所有惰性匹配情形如下:

贪婪量词惰性量词
{m,n}{m,n}?
{m}{m,}?
???
++?
**?

对惰性匹配的记忆方式是:量词后面加个问号,问一问你知足了吗,很贪婪吗?

1.4 多选分支

一个模式可以实现横向和纵向模糊匹配。而多选分支可以支持多个子模式任选其一。

具体形式: (p1|p2|p3),其中 p1、p2、p3 是子模式,用 | 管道符分割,表示其中任何之一。

例如匹配字符串 ‘ab’ 和 ‘cd’ 可以使用 /ab|cd/

const regex = /ab|cd/g;
const str = 'ab sdfs, cd sagfasf';
str.match(regex);// ..

const regex2 = /good|goodbay/g;
const str2 = 'goodbay';
str2.match(regex2);// ..


const regex2 = /goodbay|good/g;
const str2 = 'goodbay';
str2.match(regex2);// ..

// 这说明了什么?

上面的实例,

说明分支结构也是惰性的,当前面的匹配上了,后面的就不再尝试了

1.5案例分析
以上讲了匹配字符,无非就是字符组,量词和分支结构的组合而已。

1.5.1匹配 16 进制颜色值

// 匹配 颜色值
// 分析 16 进制字符,可以使用字符组 [0-9a-fA-F]
// 字符可以出现 3 次或 6 次,需要使用量词和分支结构(这里一定要注意先后顺序)

const regex = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;
const str = '#ddd #1fsd34 #FFF #fc0DED';
str.match(regex);

1.5.2匹配时间

// 要求匹配 24 小时制  23:59    01:07
// 分析: 四位数字,第一位为0-2
// 当第一位为 2 第二位为 0 1 2 3 其他情况 第二位为 [0-9]
// 第三位数字 [0-5] 第四位 [0-9]

const regex = /^([01][0-9]|[2][0-3]):[0-5][0-9]$/;
regex.test('23:59');
regex.test('01:07');


// 可以匹配 1:7 
const regex = /^(0?[0-9]|1[0-9]|[2][0-3]):(0?[0-9]|[1-5][0-9])$/;

以上使用了 ^ 和 $ ,分别表示字符串的开头和结尾。客观不要着急,下一大章节会学习到

1.5.3匹配日期

比如 yyyy-mm-dd 格式匹配 :2022-08-02

// 分析:年 四位数字 可用 [0-9]{4}
// 月:(0[1-9]|1[0-2])
// 日:(0[1-9]|[12][0-9]|3[01])
const regex = /^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/;
regex.test('2022-08-02');

1.5.4window 操作系统文件路径

// D:\study\react-admin-app\package.json
// D:\study\react-admin-app
// D:\study
// D:\

// 分析: 磁盘:D:\     使用 [a-zA-Z]:\  (磁盘名称不区分大小写,这里注意 \ 需要转义)
// 文件夹名: 不能包括一些特殊字符 可以使用排除字符组 [^\:*<>|"?\r\n/]
// 		而且名字不能为空,至少有一个字符,也就是要使用量词 + 。
//    因此匹配文件夹\ ,可用 [^\:*<>|"?\r\n/]+\
//    而且 文件夹可以出现任意次,([^\:*<>|"?\r\n/]+\)*
//    最后一部分可以是 文件夹没有\ 因此需要添加 ([^\:*<>|"?\r\n/]+)?

const regex = /^[a-zA-Z]:\([^\:*<>|"?\r\n/]+\)*([^\:*<>|"?\r\n/]+)?$/;
regex.test('D:\study\react-admin-app\package.json')
regex.test('D:\study\react-admin-app')
regex.test('D:\study\')
regex.test('D:\')

1.5.5 匹配 id

// <div id="myId" class="my-class"></div>
// 提取出 id="container"

// 最开始的想法
const regex = /id=".*"/g; // 思考下有什么缺点

// . 是通配符,本身就匹配双引号,而量词 * 又是贪婪的,直到遇到最后一个"才会停下来。
//    会把class 一块匹配进来。怎么解决?

// 使用惰性匹配
const regex2 = /id=".*?"/
const str = '<div id="myId" class="my-class"></div>';
str.match(regex2)[0];


const regex3 = /id="[^"]*"/;
str.match(regex3)[0];

在学习到这里的时候,我们已经学会了字符组和量词,已经可以解决大部分常见的情形。到这里的学习,JavaScript 正则已经算是入门了。
未完,待续

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值