💻【JavaScript】正则表达式🏠专栏:JavaScript
👀个人主页:繁星学编程🍁
🧑个人简介:一个不断提高自我的平凡人🚀
🔊分享方向:目前主攻前端,其他知识也会阶段性分享🍀
👊格言:☀️没有走不通的路,只有不敢走的人!☀️
👉让我们一起进步,一起成为更好的自己!!!🎁
文章目录
- 【JavaScript】正则表达式
- 一. 什么是正则表达式?
- 二. 创建正则表达式
- 三. 正则表达式修饰符
- 四. 正则表达式的方法
- (1) test()
- (2) search()
- (3) replace()
- (4) exec()
- (5) match()
- (6) split()
- 五. 正则表达式模式
- (1) 方括号
- (2) 元字符
- (3) 量词
- (4) 正则语法
- (5) 重复元字符
- (6) 正则的捕获方式
- 六. ES9新特性(正则扩展)
- (1) 命名捕获分组
- (2) 反向断言
- (3) dotAll 模式
- 七. 案例
【JavaScript】正则表达式
正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。
一. 什么是正则表达式?
正则表达式是由一个字符序列形成的搜索模式。
当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容。
正则表达式可以是一个简单的字符,或一个更复杂的模式。
正则表达式可用于所有文本搜索和文本替换的操作。
正则的两大特性:
-
懒惰
每次捕获的时候都会从字符串[0]开始检索
解决:给正则添加标识符g -
贪婪
每次在捕获内容的时候,尽可能多的去捕获内容
解决:使用非贪婪限定符(在原来的限定符后面加一个?)
// 贪婪捕获
var str = '1234567abcd'
var reg = /\d*/
console.log(reg.exec(str)); // ['1234567', index: 0, input: '1234567abcd', groups: undefined]
贪婪限定符:(*、+、?、{n,}、{n,m})
// 贪婪限定符
var reg = /<div.*>/
console.log(reg.exec(str)); // '<div class="box" id="box"><span></span></div>'
非贪婪限定符:(*?、+?、??、{n,}?、{n,m}?)
// 非贪婪限定符
var reg = /<div.*?>/
console.log(reg.exec(str)); // '<div class="box" id="box">'
二. 创建正则表达式
(1) 内置构造函数方式创建
var reg = new RegExp("正则","匹配模式");
// eg:
var reg = new RegExp('abcd', 'ig');
console.log(reg.test('abCD')); // true
(2) 字面量方式创建
var reg = /正则表达式/匹配模式
// eg:
var reg = /abcd/ig;
console.log(reg.test('abCD')); // true
在构造函数中可以传递一个匹配模式作为第二个参数。
语法:
var 变量 = /正则表达式/匹配模式
//使用构造函数创建正则表达式
var a = new RegExp("a","i");
//使用字面量创建正则表达式
var reg = /a/i
console.log(typeof reg);//typeof 用于检查正则对象,会返回object
console.log(reg.test("Abc"))//结果:true
三. 正则表达式修饰符
修饰符 可以在全局搜索中不区分大小写:
i(ignore case):忽略大小写
g(global):执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)
m(multiple lines):执行多行匹配
设置匹配模式时,可以都不设置,也可以设置1个,也可以全设置,设置时没有顺序要求。
四. 正则表达式的方法
(1) test()
test() 方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。
语法:正则表达式.test(字符串)
var a = new RegExp("e");//检查下列句子中是否含有e
document.write(a.test("There is a good thing"));
<!-- 结果:true -->
(2) search()
search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,并$\color{red} {返回子串的起始位置} $。
语法:字符串.search(正则表达式)
实例:使用正则表达式搜索 “Root” 字符串,且不区分大小写:
var str = "Visit Root!";
var n = str.search(/Root/i);
输出结果:6
(3) replace()
replace() 方法用于在字符串中用一些字符串替换另一些字符串,或替换一个与正则表达式匹配的子串。
实例
使用正则表达式且不区分大小写将字符串中的 Cat 替换为 Root:
var str = "Visit Cat !";
var txt = str.replace(/cat/i,"Root");
结果输出为:
Visit Root !
// eg:
// 批量替换敏感词
var arr = ['HH', 'MM', 'NN']
var str = 'aHHdfasMMdfaNNdsfaNNsNNdffas'
var reg = new RegExp(arr.join("|"), "g")
console.log(str.replace(reg, '**')); // a**dfas**dfa**dsfa**s**dffas
(4) exec()
exec() 方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null。
语法:正则表达式.exec(字符串)
var reg=/\d/;
var str="ab56efg";
var res=reg.exec(str);
console.log(res);//返回一个数组,内容是4
//字符串中满足正则表达式的部分提取出来
//遇到满足条件的就返回,所以只返回4
(5) match()
match() 方法检索返回一个字符串匹配正则表达式的结果。
语法:字符串.match(正则表达式)
var reg=/[a-z]/g;
var str="ab56efg";
var res=str.match(reg); //字符串中满足表达式的部分提取出来
console.log(res);//结果:a,b,e,f,g
区别: 正则表达式.exec(字符串),正则表达式提供的方法 字符串.match(正则表达式) 字符串的方法
相同: 都返回一个数组,只要匹配到符合规则的数据就返回
(6) split()
将一个字符串拆分为一个数组
语法:字符串.match(正则表达式/字符串)
var str = "1j1j1k2d7o";
var result = str.split("k");
console.log(result);
//结果:"1j1j1,2d7o"
var result = str.split(/[A-z]/);
console.log(result);
//结果:"1,1,1,2,7"
五. 正则表达式模式
(1) 方括号
方括号用于查找某个范围内的字符:
表达式 | 描述 |
---|---|
[abc] | 查找方括号之间的任何字符。 |
[0-9] | 查找任何从 0 至 9 的数字。 |
(x|y) | 查找任何以 | 分隔的选项。 |
(2) 元字符
元字符(Metacharacter)是拥有特殊含义的字符:
元字符 | 描述 |
---|---|
. | (小数点)默认匹配除换行符之外的任何单个字符。 |
\w | 匹配一个单字字符(字母、数字或者下划线)。等价于 [A-Za-z0-9_] 。 |
\W | 匹配一个非单字字符。等价于 [^A-Za-z0-9_] 。 |
\d | 查找数字(至少含有一个数字(0~9)) |
\D | 查找非数字字符(至少含有一个非数字) |
\s | 查找空白字符(至少含有一个空白字符(空格、缩进、\b…)) |
\S | 查找非空白字符(至少含有一个不是空白字符) |
\b | 匹配单词边界 |
\B | 匹配非单词边界 |
\0 | 查找NUL字符 |
\n | 查找换行符 |
\f | 查找换页符 |
\r | 查找回车符 |
\t | 查找制表符 |
\v | 查找垂直制表符 |
\xxx | 查找以八进制 xxx 规定的字符 |
\xdd | 查找以十六进制 dd 规定的字符 |
\uxxxx | 查找以十六进制 xxxx 规定的 Unicode 字符 |
实例
var reg = /\W/ //true
console.log(reg.test("!@#!"))
var reg = /\D/ //false
console.log(reg.test("123"))
var reg = /\bchild\b/ //false
console.log(reg.test("hello children"))
(3) 量词
量词 | 描述 |
---|---|
? | 出现0次或一次 |
+ | 出现一次或多次 |
* | 出现0次或多次 |
{n} | 出现n次 |
{n,m} | 出现n到m次 |
{n,} | 至少出现n次 |
实例
var reg = /a{3}/;//判断a是否连续出现3次
console.log(reg.test("aaabc"));//true
console.log(reg.test("abc"));//false
var reg = /(ab){3}/;//判断ab是否连续出现3次
console.log(reg.test("abababc"));//true
console.log(reg.test("abc"));//false
var reg = /ab{1,3}c/;//判断b是否连续出现1-3次
console.log(reg.test("abbbc"));//true
console.log(reg.test("abbbbbc"));//false
console.log(reg.test("bac"));//false
(4) 正则语法
正则 | 描述 |
---|---|
| | 或 |
[ ] | 或 |
[^ ] | 除了 |
[a-z] | 小写字母 |
[A-Z] | 大写字母 |
[A-z] | 任意字母 |
^ | 开头 |
$ | 结尾 |
实例:
//检查字符串中是否含有a或b
var reg = /a|b/
console.log(reg.test("bcd"))//结果:true
//检查字符串中是否含有字母
var reg = /[a-z]/
console.log(reg.test("bcdfsji"))//结果:true
//检查字符串中是否含有abd或abc或abf
var reg = /ab[cdf]/
console.log(reg.test("bcabcji"))//结果:true
//检查一个字符串是否以a结尾
var reg = /a$/
console.log(reg.test("bcabcjia"))//结果:true
//如果在正则表达式中同时使用^ $则要求必须完全符合正则表达式
var reg = /^a$/
console.log(reg.test("as"))//结果:false
(5) 重复元字符
符号: \数字
作用: 表示重复第n个小括号的内容,要求和第n个小括号的内容一模一样
// 表示这个()里面的整体内容出现2次就可以。不要求一模一样
// var reg1 = /^(abc|def){2}$/
// 表示 \1 位置 需要出现一个 和 第一个 小括号 一模一样的内容
var reg1 = /^(abc|def)\1$/
console.log(reg.test('abcabc')); // true
console.log(reg.test('defdef')); // true
console.log(reg.test('abcdef')); // false
var reg2 = /^(abc|def)(哈哈|嘻嘻)\2$/
console.log(reg.test('abc哈哈哈哈')); // true
console.log(reg.test('abc哈哈嘻嘻')); // false
console.log(reg.test('abc嘻嘻嘻嘻')); // true
(6) 正则的捕获方式
语法:正则表达式.exec(字符串)
作用:始字符串中捕获到符合正则规则的字符串片段
返回值:
-
当原始字符串没有符合规则的时候,返回null
-
当原始字符串由符合规则的片段的时候:
返回值必然是一个数组,数组的[0] 是捕获出来的字符串片段
-
没有(), 没有g
不管写多少次,只能捕获第一组匹配规则的字符串片段
var reg = /\d{3}/ var str = 'adfa123sals456hdfl789kasakhdf012' var res = reg.exec(str) console.log(res); // ['123', index: 4, input: 'adfa123sals456hdfl789kasakhdf012', groups: undefined] console.log(reg.exec(str)); // ['123', index: 4, input: 'adfa123sals456hdfl789kasakhdf012', groups: undefined] console.log(reg.exec(str)); // ['123', index: 4, input: 'adfa123sals456hdfl789kasakhdf012', groups: undefined]
-
有()
会在返回值数组的[1]开始,依次是每一个()中单独的内容
var reg = /(\d{2})(\d{2})(\d{2})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|x)/ var str = '22230120050101123x' console.log(reg.exec(str)); // ['22230120050101123x', '22', '23', '01', '2005', '01', '01', '12', '3', 'x', index: 0, input: '22230120050101123x', groups: undefined]
-
有g
g 叫做全局标识符
第二次捕获开始会从第一次捕获的结束为止开始检索
直到找不到内容,返回null
var reg = /\d{3}/g var str = 'adfa123sals456hdfl789kasakhdf012' console.log(reg.exec(str)); // ['123', index: 4, input: 'adfa123sals456hdfl789kasakhdf012', groups: undefined] console.log(reg.exec(str)); // ['456', index: 11, input: 'adfa123sals456hdfl789kasakhdf012', groups: undefined] console.log(reg.exec(str)); // ['789', index: 18, input: 'adfa123sals456hdfl789kasakhdf012', groups: undefined]
-
匹配但是不捕获
当我们需要使用()这个整体作用,但是不需要把()里面的内容单独捕获的时候:可以书写(?😃
六. ES9新特性(正则扩展)
(1) 命名捕获分组
捕获:对正则匹配的数据进行(.*)单独提取。
// 正则扩展:命名捕获分组
// 声明一个字符串
let str = '<a href="http://www.baidu.com">你好</a>';
// 需求:提取url和标签内文本
// 之前的写法
const reg = /<a href="(.*)">(.*)<\/a>/;
// 执行
const result = reg.exec(str);
console.log(result);
// 结果是一个数组,第一个元素是所匹配的所有字符串
// 第二个元素是第一个(.*)匹配到的字符串
// 第三个元素是第二个(.*)匹配到的字符串
// 我们将此称之为捕获
console.log(result[1]);
console.log(result[2]);
const reg1 = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
const result1 = reg1.exec(str); console.log(result1);
// 这里的结果多了一个groups
// groups:
// text:"你好"
// url:"http://www.baidu.com"
console.log(result1.groups.url);
console.log(result1.groups.text);
结果:
(2) 反向断言
断言:判断这次的匹配结果是否正确
正向断言/反向断言 做一个唯一性的识别
正向断言(目标的后面)
let str = "JS314你知道么5呀";
// 需求:我们只想匹配到5
// 正向断言
const reg = /\d+(?=啦)/;
// 前面是数字后面是啦
const result = reg.exec(str);
结果:
反向断言(目标的前面)
// 反向断言
const reg1 = /(?<=么)\d+/;
// 后面是数字前面是么
const result1 = reg.exec(str);
console.log(result1);
结果:
(3) dotAll 模式
dot就是. 元字符,表示除换行符之外的任意单个字符
之前的写法:
let str = `
<ul>
<li>
<a href="#">a</a>
<p>b</p>
</li>
<li>
<a href="#">c</a>
<p>d</p>
</li>
</ul>
`;
const reg = /<li>\s+<a href="#">(.*?)<\/a>\s+<p>(.*?)<\/p>/;
console.log(reg.exec(str));
结果:
使用dotAll后:
let str = `
<ul>
<li>
<a href="#">a</a>
<p>b</p>
</li>
<li>
<a href="#">c</a>
<p>d</p>
</li>
</ul>
`;
// const reg = /<li>\s+<a href="#">(.*?)<\/a>\s+<p>(.*?)<\/p>/g;
const reg = /<li>.*?<a href="#">(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;
// console.log(reg.exec(str));
let result;
while ((result = reg.exec(str))) console.log(result);
g为全局匹配 匹配不到是返回null,结束循环
结果:
七. 案例
案例一:书写正则验证用户名
规则:
- 6 ~ 12 位
- 只能包含数字字母下划线 \w
- 不能以 下划线开头
var reg = /^[0-9a-zA-Z]\w{5,11}$/
案例二:书写正则验证邮箱
规则:
- @ 前面, 和用户名规则一致
- 邮箱类型只接受 163 qq sina
- 后缀只接受 com cn
var reg = /^[0-9a-zA-Z]\w{5,11}@(163|qq|sina)\.(com|cn)$/
案例三:书写正则验证手机号
规则:
- 前面有可能带有 +86 有可能没有 ? {0,1}
- +86 和 电话号之间有可能有空格有可能没有
- 号段只接受 133 135 188
var reg = /^(\+86 ?)?(133|135|188)\d{8}$/
案例四:书写正则验证 0 ~ 255 的数字
var reg = /^(\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])$/
<!-- 验证:0 ~ 666 -->
var reg = /^(\d{1,2}|[1-5]\d{2}|6[0-5]\d|66[0-6])$/
结束语:
希望对您有一点点帮助,如有错误欢迎小伙伴指正。
👍点赞:您的赞赏是我前进的动力!
⭐收藏:您的支持我是创作的源泉!
✍评论:您的建议是我改进的良药!
一起加油!!!💪💪💪