Flask接口签名sign原理与实例代码浅析
263
2022-06-11
一、正则表达式简介
1、什么是正则表达式
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
简单的说,就是按照某种规则去匹配符合条件的字符串。
2、可视化正则表达式工具
Regexper:https://regexper.com/
二、RegExp对象
实例化RegExp的两种方式。
两种方式定义RegExp对象。
1、字面量
let reg = /[a-z]{3}/gmi;
let reg = /[a-z]{3}/g;
let reg = /[a-z]{3}/m;
let reg = /[a-z]{3}/i;
标志
g global 代表全局搜索。如果不添加,搜索到第一个匹配停止。
m Multi-Line 代表多行搜索。
i ignore case 代表大小写不敏感,默认大小写敏感。
2、构造函数
let reg = new RegExp('\\bis\\b', 'g');
因为JavaScript字符串中\属于特殊字符,需要转义。
三、元字符
把元字符当作转义字符。
正则表达式有两种基本字符类型组成。
原义文本字符
元字符
1、原义文本字符
表示原本意义上是什么字符,就是什么字符。
2、元字符
是在正则表达式中有特殊含义的非字母字符。
* + ? $ ^ . | \ ( ) { } [ ]
字符
含义
\t
水平制表符
\v
垂直制表符
\n
换行符
\r
回车符
\0
空字符
\f
换页符
\cX
控制字符,与X对应的控制字符(Ctrl + X)
类似于转义字符。
四、字符类
表示符合某种特性的字符类别。
使用元字符[]可以构建一个简单的类。
所谓类是指符合某些特性的对象,一个泛指,而不是某个字符。
例子
表达式[abc]把字符a或b或c归为一类,表达式可以匹配这一类中的任意一个字符。
// replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
'a1b2c3d4e5'.replace(/[abc]/g, '0'); //010203d4e5
字符类取反
我们想要替换不是abc中任意一个字符的字符。
// 元字符 ^ 创建一个 反向类/负向类
'abcdefg'.replace(/[^abc]/g, '0'); //abc0000
五、范围类
匹配这一个范围内的字符。
如果我们想要匹配数字0-9,那么我们可能会这样写[0123456789]。
如果我们想要匹配26个字母,那么我们可能会这样写[abcdefghijklmnopqrstuvwxyz]。
这样略显麻烦,所以才会有范围类。
例子
// 替换所有数字
'a1c2d3e4f5'.replace(/[0-9]/g, 'x'); //axcxdxexfx
// 替换所有小写字母
'a1c2d3e4f5'.replace(/[a-z]/g, 'x'); //x1x2x3x4x5
// []组成的类内部是可以连写的。替换所有大小写字母
'a1C2d3E4f5G6'.replace(/[a-zA-Z]/g, '*'); //*1*2*3*4*5*6
疑问
如果我想替换数字,并且连带-符号也一起替换呢?
// 替换所有数字和横杠
'2018-5-21'.replace(/[0-9-]/g, '*'); //*********
六、预定义类
一些已经定义的类,可以直接使用。
字符
等价类
含义
.
[^\r\n]
除了回车、换行之外的所有字符
\d
[0-9]
数字字符
\D
[^0-9]
非数字字符
\s
[\t\n\x0B\r]
空白符
\S
[^\t\n\x0B\r]
非空白符
\w
[a-zA-Z_0-9]
单词字符(字母、数字、下划线)
\W
[^a-zA-Z_0-9]
非单词字符
例子
替换一个 ab + 数字 + 任意字符 的字符串
// 写法1
'ab0c'.replace(/ab[0-9][^\r\n]/g, 'TangJinJian'); //TangJianJian
// 写法2
'ab0c'.replace(/ab\d./g, 'TangJinJian'); //TangJianJian
七、单词边界
字符
含义
^
以xxx开始(不在中括号内时的含义)
$
以xxx结束
\b
单词边界
\B
非单词边界
例子
我想替换的字符串,属于那种只在开头出现的。
'YuYan is a boy, YuYan'.replace(/^YuYan/g, 'TangJinJian'); //TangJinJian is a boy, YuYan
我想替换的字符串,属于那种只在结尾出现的。
'YuYan is a boy, YuYan'.replace(/YuYan$/g, 'TangJinJian'); //YuYan is a boy, TangJinJian
单词边界例子。
// 替换所有is为0
'This is a man'.replace(/is/g, '0'); //Th0 0 a man
// 替换所有is前面带有单词边界的字符串
'This is a man'.replace(/\bis/g, '0'); //This 0 a man
// 替换所有is前面没有单词边界的字符串
'This is a man'.replace(/\Bis\b/g, '0'); //Th0 is a man
八、量词
用来处理连续出现的字符串。
字符
含义
?
出现零次或一次(最多出现一次)
+
出现一次或多次(至少出现一次)
*
出现零次或多次(任意次)
{n}
出现n次
{n,m}
出现n到m次
{n,}
至少出现n次
我想替换字符串中连续出现10次的数字为*。
'1234567890abcd'.replace(/\d{10}/, '*'); //*abcd
我想替换字符串中的QQ号码。
'我的QQ是:10000'.replace(/[1-9][0-9]{4,}/, '19216811'); //我的QQ是:19216811
九、贪婪模式
尽可能多的匹配。
有这样的一种场景下的正则表达式,/\d{3,6}/该替换3个数字还是6个数字呢,4、5个数字?
// 贪婪模式会尽可能的往多的方面去匹配
'123456789'.replace(/\d{3,6}/, 'x'); //x789
'123456789'.replace(/\d+/, 'x'); //x
'123456789'.replace(/\d{3,}/, 'x'); //x
十、非贪婪模式
尽可能少的匹配。
如果我们想要最低限度的替换呢?
// 非贪婪模式使用 ? 尽可能的往少的方面去匹配
'12345678'.replace(/\d{3,6}?/g, 'x'); //xx78
'123456789'.replace(/\d{3,6}?/g, 'x'); //xxx
因为有g标志,会匹配这段字符串里所有符合规则的字符串。
第一个规则/\d{3,6}?/g,12345678中有两个符合条件的字符串,是123和456。所以替换结果是xx78。
第二个规则/\d{3,6}?/g,123456789中有三个符合条件的字符串,是123、456和789。所以替换结果是xxx。
十一、分组
括号里的一些规则,分为一组。
我想替换连续出现3次的字母和数字。
//没有分组的情况下,后面的量词,只是表示匹配3次数字。
'a1b2d3c4'.replace(/[a-z]\d{3}/g, '*'); //a1b2d3c4
//有分组的情况下,分组后面的量词,表示符合这个分组里规则的字符串,匹配3次。
'a1b2d3c4'.replace(/([a-z]\d){3}/g, '*'); //*c4
1、或
分组里有两种规则,只要满足其中一种即可匹配。
//我想把ijaxxy和ijcdxy都替换成*
'ijabxyijcdxy'.replace(/ij(ab|cd)xy/g, '*'); //**
2、反向引用
可以把分组视为变量,来引用。
//我想把改变年月日之间的分隔符
'2018-5-22'.replace(/(\d{4})-(\d{1,2})-(\d{1,2})/g, '$1/$2/$3'); //2018/5/22
//我想替换日期,并且更改顺序
'2018-5-22'.replace(/(\d{4})-(\d{1,2})-(\d{1,2})/g, '$2/$3/$1'); //5/22/2018
3、忽略分组
忽略掉分组,不捕获分组,只需要在分组内加上?:
// 忽略掉匹配年的分组后,匹配月的分组变成了$1,日的分组变成了$2
'2018-5-22'.replace(/(?:\d{4})-(\d{1,2})-(\d{1,2})/g, '$1/$2/$3'); //5/22/$3
十二、前瞻
正则表达式从文本头部向尾部开始解析,文本尾部方向,称为“前”。
前瞻就是在正在表达式匹配到规则的时候,向前检查是否符合断言,后顾/后瞻方向相反。
JavaScript不支持后顾。
符合和不符合特定断言称为肯定/正向匹配和否定/负向匹配。
名称
正则
含义
正向前瞻
exp(?=assert)
负向前瞻
exp(?!assert)
正向后顾
exp(?<=assert)
JavaScript不支持
负向后顾
exp(?
JavaScript不支持
例子
有这样一个单词字符+数字格式的字符串,只要满足这种格式,就把其中的单词字符替换掉。
'a1b2ccdde3'.replace(/\w(?=\d)/g, '*'); //*1*2ccdd*3
有这样一个单词字符+非数字格式的字符串,只要满足这种格式,就把前面的单词字符替换掉。
'a1b2ccdde3'.replace(/\w(?!\d)/g, '*'); //a*b*****e*
十三、RegExp对象属性
global是否全文搜索,默认false。
ignore case是否大小写敏感,默认是false。
multiline多行搜索,默认值是false。
lastIndex是当前表达式匹配内容的最后一个字符的下一个位置。
source正则表达式的文本字符串。
let reg1 = /\w/;
let reg2 = /\w/gim;
reg1.global; //false
reg1.ignoreCase; //false
reg1.multiline; //false
reg2.global; //true
reg2.ignoreCase; //true
reg2.multiline; //true
十四、RegExp对象方法
1、RegExp.prototype.test()
用来查看正则表达式与指定的字符串是否匹配。返回true或false。
let reg1 = /\w/;
reg1.test('a'); //true
reg1.test('*'); //false
加上g标志之后,会有些区别。
let reg1 = /\w/g;
// 第一遍
reg1.test('ab'); //true
// 第二遍
reg1.test('ab'); //true
// 第三遍
reg1.test('ab'); //false
// 第四遍
reg1.test('ab'); //true
// 第五遍
reg1.test('ab'); //true
// 第六遍
reg1.test('ab'); //false
实际上这是因为RegExp.lastIndex。每次匹配到之后,lasgIndex会改变。
lastIndex是正则表达式的一个可读可写的整型属性,用来指定下一次匹配的起始索引。
let reg = /\w/g;
// 每次匹配到,就会把lastIndex指向匹配到的字符串后一个字符的索引。
while(reg.test('ab')) {
console.log(reg.lastIndex);
}
// 1
// 2
reg.lastIndex初始时为0,第一个次匹配到a的时候,reg.lastIndex为1。第二次匹配到b的时候,reg.lastIndex为2。
正则表达式
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~