正则表达式

本文将对正则表达式做一个详细的介绍。

**正则表示是用于匹配字符串中字符组合的模式。**在JavaScript中,正则表达式也是对象【引用数据类型中RegExp类型】。这些模式被用于RegExp的exec和test方法,以及String中的match、matchAll、replace、search和split方法。

特点:

(1)灵活性、逻辑性和功能性非常强。

(2)可以迅速地用极简单的方式达到字符串的复杂控制。

创建正则表达式

方式一:通过调用RegExp对象的构造函数创建

javascript 复制代码
let regexp = new RegExp(/123/);
console.log(regexp); //  /123/

方式二:使用字面量创建正则表达式

javascript 复制代码
let rg = /123/

测试正则表达式

test()方法,这是正则对象方法,用于检测字符串是否符合该规则,该对象会返回true或false,其参数是测试字符串。

javascript 复制代码
let rg = /123/;
console.log(rg.test(123));//匹配字符中是否出现123  出现结果为true
console.log(rg.test('abc'));//匹配字符中是否出现123 未出现结果为false

正则表达式中的特殊字符

正则表达式修饰符

  • /i :执行对大小写不敏感的匹配。
  • /g :执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
  • /m :执行多行匹配

正则表达式模式

  1. [abc] :查找括号之间的任何字符。
  2. [^abc] :查找任何不在方括号之间的字符。
  3. [0-9] :查找任何从 0 至 9 的数字。
  4. [^0-9] :查找任何不在括号内的字符(任何非数字)。
  5. (x|y) :查找任何指定的选项。
javascript 复制代码
let rg = /[abc]/; // 只要包含有a 或者 包含有b 或者包含有c 都返回为true
console.log(rg.test('andy'));//true
console.log(rg.test('baby'));//true
console.log(rg.test('color'));//true
console.log(rg.test('red'));//false
console.log("---------------------------------------------------------------")
let rg1 = /^[abc]$/; // 三选一 只有是a 或者是 b  或者是c 这三个字母才返回 true
console.log(rg1.test('aa'));//false
console.log(rg1.test('a'));//true
console.log(rg1.test('b'));//true
console.log(rg1.test('c'));//true
console.log(rg1.test('abc'));//false
console.log("---------------------------------------------------------------")
// - 短横线 表示一个范围
let reg = /^[a-z]$/ //26个英文字母任何一个字母返回 true  - 表示的是a 到z 的范围
console.log(reg.test('a'));//true
console.log(reg.test('z'));//true
console.log(reg.test('A'));//false
console.log("----------------------------------------------------------------")
// 字符组合
let reg1 = /^[a-zA-Z0-9]$/; // 26个英文字母(大写和小写都可以)任何一个字母返回 true
//取反 方括号内部加上 ^ 表示取反,只要包含方括号内的字符,都返回 false 。
let reg2 = /^[^a-zA-Z0-9]$/;
console.log(reg2.test('a'));//false
console.log(reg2.test('B'));//false
console.log(reg2.test(8));//false
console.log(reg2.test('!'));//true

元字符

元字符是具有特殊含义的字符:

  1. . :这里的.(点)表示查找单个字符,除了换行符或行终止符。
  2. \w :查找单词字符。【类似但不等价于"[A-Za-z0-9_]",这里的"单词"字符使用Unicode字符集。】
  3. \W:查找非单词字符。【匹配任何非单词字符。等价于"[^A-Za-z0-9_]"。】
  4. \d :查找数字
  5. \D:查找非数字字符。
  6. \s :查找空白字符。
  7. \S:查找非空白字符。
  8. \b :在单词的开头/结尾查找匹配项,开头如下:\bHI,结尾如下:HI\b。
  9. \B :查找匹配项,但不在单词的开头/结尾处
  10. \0 :查找NULL字符
  11. \n :查找换行符
  12. \f :查找换页符
  13. \r :查找回车符
  14. \t :查找制表符
  15. \v:查找垂直制表符
  16. \xxx:查找以八进制数 xxx 规定的字符。
  17. \xdd:查找以十六进制数 dd 规定的字符。
  18. \uxxxx:查找十六进制数 xxxx 规定的 Unicode 字符。

量词

  1. n+:匹配至少包含一个n的字符串。
  2. n*:匹配包含零个或多个n的字符串。
  3. n?:匹配包含零个或一个n的字符串。
  4. n{X}:匹配包含X个n的序列的字符串。
  5. n{X, Y}:匹配包含X至Y个n的序列的字符串。
  6. n{X,}:匹配包含至少X个n的序列的字符串。
  7. n$:匹配以n结尾的字符串。
  8. ^n:匹配以n开头的字符串。
  9. ?=n:匹配其后紧接指定字符串n的字符串。
  10. ?!n:匹配其后没有紧接指定字符串n的字符串。

括号匹配区分

  • 大括号------量词符。里面表示重复次数
  • 中括号------字符集合。匹配方括号中的任意字符
  • 小括号------表示优先级

核心匹配

  1. * :重复0次或多次
  2. +:重复1次或多次
  3. ?:重复0次或1次
  4. {n}:重复n次
  5. {n,}:重复n次或更多次
  6. {n,m}:重复n到m次
javascript 复制代码
// 量词符:用来设定某个模式出现的次数
// 简单理解:就是让下面的a这个字符重复多少次

var reg = /^a$/;   //以a开头

// * :相当于 >=0 可以出现0次或者很多次
var reg = /^a*$/;   //以a开头,匹配0个或多个a
console.log(reg.test('')); //true   0个a
console.log(reg.test('a'));//true   一个a
console.log(reg.test('aaaa')); //true   多个a
console.log("---------------------------------------------")
// + :相当于 >=1 可以出现1次或者很多次
var reg = /^a+$/;   //以a开头,匹配至少1个a
console.log(reg.test(''));//false   0个a
console.log(reg.test('a'));//true   1个a
console.log(reg.test('aaaa'));//true    多个a
console.log("---------------------------------------------")
// ? :相当于 1 || 0 重复1次或者0次
var reg = /^a?$/;   //以a开头,匹配0个或1个a
console.log(reg.test('')); //true   0个a
console.log(reg.test('a'));//true   1个a
console.log(reg.test('aaaa'));//false    多个a
console.log("---------------------------------------------")
// {3} :就是重复3次
var reg = /^a{3}$/; //以a开头,匹配3个a
console.log(reg.test(''));//false   0个a
console.log(reg.test('a'));//false   1个a
console.log(reg.test('aaaa'));//false   多个a
console.log(reg.test('aaa'));//true   3个a
console.log("---------------------------------------------")
// {3,}: 大于等于3 >=3
var reg = /^a{3,}$/;    //以a开头,匹配3个a或3个以上的a
console.log(reg.test(''));//false   0个a
console.log(reg.test('a'));//false   1个a
console.log(reg.test('aaaa'));//true   多个a
console.log(reg.test('aaa'));//true   3个a
console.log("---------------------------------------------")
// {3,16}: 等于3 并且 小于等于16
var reg = /^a{3,16}$/;  //以a开头,匹配3-16个a
console.log(reg.test(''));//false   0个a
console.log(reg.test('a'));//false   1个a
console.log(reg.test('aaa'));//true   3个a
console.log(reg.test('aaaa'));//true   4个a
console.log(reg.test('aaaaaaaaaaaaaaaa'));//true   16个a
console.log(reg.test('aaaaaaaaaaaaaaaaa'));//false   17个a

边界符

正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符:

  1. ^:表示匹配行首的文本(以谁开始)
  2. $:表示匹配行尾的文本(以谁结束)

PS:如果^和$在一起匹配,则表示必须是精确匹配。

javascript 复制代码
var rg = /abc/; // 正则表达式里面不需要加引号 不管是数字型还是字符串型
// /abc/ 只要包含有abc这个字符串返回的都是true
console.log(rg.test('abc')); // true
console.log(rg.test('abcd')); // true
console.log(rg.test('aabcd')); // true
console.log('---------------------------');
var reg = /^abc/;   // 必须以abc开头
console.log(reg.test('abc')); // true
console.log(reg.test('abcd')); // true
console.log(reg.test('aabcd')); // false
console.log('---------------------------');
var reg1 = /^abc$/; // 精确匹配 要求必须是 abc字符串才符合规范
console.log(reg1.test('abc')); // true
console.log(reg1.test('abcd')); // false
console.log(reg1.test('aabcd')); // false
console.log(reg1.test('abcabc')); // false

正则修复边界

javascript 复制代码
// 使用 正则表达式边界修复错误字符串
buggyMultiline = `tey, ihe light-greon apple
tangs on ihe greon traa`;

// 1) 使用 ^ 修正字符串开始处和换行后的匹配。
buggyMultiline = buggyMultiline.replace(/^t/gim,'h');
console.log(1, buggyMultiline); // 修复 'tey'=>'hey'(字符串开始) , 'tangs'=>'hangs'(换行后)
// 1 'hey, ihe light-greon apple\nhangs on ihe greon traa'  //把每行开头的 t 换成了 h

// 2) 使用 $ 修正字符串结尾处的匹配。
buggyMultiline = buggyMultiline.replace(/aa$/gim,'ee.');
console.log(2, buggyMultiline); // 修复 'traa' => 'tree'.
// 2 'hey, ihe light-greon apple\nhangs on ihe greon tree.' //把每行结尾的aa换成ee.

// 3) 使用 \b 修正单词和空格边界上的字符。
buggyMultiline = buggyMultiline.replace(/\bi/gim,'t');
console.log(3, buggyMultiline); // 修复 'ihe' => 'the'  不影响 'light'.
// 3 'hey, the light-greon apple\nhangs on the greon tree.' //\b空格后的第一个字符i,替换成t

// 4) 使用 \B 匹配实体边界内的字符。
fixedMultiline = buggyMultiline.replace(/\Bo/gim,'e');
console.log(4, fixedMultiline); // 修复  'greon'  不影响'on'.
// 4 'hey, the light-green apple\nhangs on the green tree.' //\B不在空格后的o,即英文单词中的o替换成e

正则表达式前瞻后顾、负前瞻和负后顾

前瞻(先行断言)

  1. (x|y):查找指定的选项
  2. ?=n:匹配其后紧接指定字符串n的字符串
  3. x(?=y):匹配x,只有当x后面跟着y,这叫做先行断言。例如:
    • /Jack(?=Sprat)/ 会匹配到'Jack'仅当它后面跟着'Sprat'。
    • /Jack(?=Sprat|Frost)/ 匹配'Jack'仅当它后面跟着'Sprat'或者是'Frost'。
    • 但是'Sprat'和'Frost'都不是匹配结果的一部分。

首先使用括号()来提升优先级,然后使用?=,对后面紧跟e的h,进行全局搜索:

javascript 复制代码
var str= 'hello hi world';
// 前瞻 查找 e 前面的h
var pe = /h(?=e)/g;
var newStr = str.replace(pe,'T');
console.log(newStr);    //Tello hi world

上述代码中,可以看到,使用正则表达式匹配出,h后面紧跟e的字符h,可以看到只有一个,把符合的h替换成T。

后顾(后行断言)

  1. (x|y):查找指定的选项
  2. (?<=y)x:匹配x,只有当x前面是y,这叫做后行断言 。例如:
    1. /(?<=Jack)Sprat/ 会匹配到' Sprat '仅仅当它前面是' Jack '。
    2. /(?<=Jack|Tom)Sprat/ 匹配'Sprat '仅仅当它前面是'Jack'或者是'Tom'。
    3. 但是'Jack'和'Tom'都不是匹配结果的一部分。

首先使用括号()来提升优先级,然后使用?<=,堆前面紧跟 l 的 d 进行全局搜索:

javascript 复制代码
// 后顾 查找l后面的 d
var str= 'hello hi world';
var pe = /(?<=l)d/g;
var newStr = str.replace(pe,'M');
console.log(newStr); //hello hi worlM

上述代码中,通过正则表达式匹配d,d前面紧跟 l ,符号的只有最后一个d,把d替换成M。

负前瞻(先行否定断言)

  1. (x|y):查找指定的选项
  2. x(?!y):当x后面不跟着y时,匹配x,这被称为正向否定查找。例如:
    1. /\d+(?!\.)/ 匹配一个数字。仅仅当这个数字后面没有跟小数点的时候。
    2. 正则表达式 /\d+(?!\.)/.exec("3.141") 匹配'141'而不是'3.141'

首先使用括号()来提升优先级,然后使用?!,对后面不是紧跟e的h进行全局搜索:

javascript 复制代码
// 负前瞻  查找h后面不是e的
var str= 'hello hi world';
var pe = /h(?!e)/g;
var newStr = str.replace(pe,'N');
console.log(newStr);    //hello Ni world

上述代码中,通过正则表达式匹配h,h后面不是e的h,这里符合的只有hi,这里把h替换为N。

负后顾(后行否定断言

  1. (x|y):查找指定的选项
  2. (?<!y)x:当x前面不是y时,匹配x,这被称为反向否定查找。例如:
    1. /(?<!-)\d+/.exec('3') 匹配到"3"。
    2. /(?<!-)\d+/.exec('-3') 因为这个数字前有负号,所以没匹配到。

首先使用括号()来提升优先级,然后使用?<!,对前面不是紧跟e的 l 进行全局搜索:

javascript 复制代码
// 负后顾  查找l前面不是e的
var str= 'hello hi world';
var pe = /(?<!e)l/g;
var newStr = str.replace(pe,'Q');
console.log(newStr); //helQo hi worQd

上述代码中,匹配l,且l前面不是e,这里符合的有两个,第一个是o前面的 l 替换为Q,第二个是d前面的 l ,替换为Q。

RegExp 对象属性

  1. constructor:返回创建RegExp对象原型的函数。
  2. global:检测是否设置了"g"修饰符。
  3. ignoreCase:检查是否设置了"i"修饰符。
  4. lastIndex:规定开始下一个匹配的索引。
  5. multiline:检查是否设置了"m"修饰符。
  6. source:返回RegExp模式的文本。

具体示例,可以参考Mdn官网:RegExp介绍

RegExp对象方法

  1. compile():在1.5版本中已弃用。编译正则表达式。
  2. exec():测试字符串中的匹配项。返回第一个匹配项。
  3. test():测试字符串中的匹配项。返回true或false。
  4. toString():返回正则表达式的字符串值。

支持正则表达式的String对象的方法

|---------|-----------------|-------------|-------------------------|
| 方法 | 描述 | Firefox(FF) | ‌Internet Explorer(IE)‌ |
| search | 检测与正则表达式匹配的值 | 1 | 4 |
| match | 找到一个或多个正则表达式的匹配 | 1 | 4 |
| replace | 替换与正则表达式匹配的子串 | 1 | 4 |
| split | 把字符串分割为字符串数组 | 1 | 4 |

案例

1、验证座机号码

javascript 复制代码
var reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/;
var reg = /^\d{3,4}-\d{7,8}$/;
console.log(reg.test('010-12345678'));// true

2、手机号验证

javascript 复制代码
//手机号验证:/^1[3|4|5|7|8][0-9]{9}$/;
//验证通过与不通过更换元素的类名与元素中的内容
let reg = /^1[3|4|5|7|8][0-9]{9}$/
console.log(reg.test('13860068008')) //true

3、验证qq号

javascript 复制代码
//QQ号验证: /^[1-9]\d{4,}$/;
//昵称验证:/^[\u4e00-\u9fa5]{2,8}$/
//验证通过与不通过更换元素的类名与元素中的内容 ,将上一步的匹配代码进行封装,多次调用即可
let reg = /^[1-9]\d{4,}$/;
console.log(reg.test(2002008000)) //true

4、正则替换replace

javascript 复制代码
var str = 'andy和red';
var newStr = str.replace('andy', 'baby');
console.log(newStr)//baby和red
console.log('---------------------------');
//等同于 此处的andy可以写在正则表达式内
var newStr2 = str.replace(/andy/, 'baby');
console.log(newStr2)//baby和red
console.log('---------------------------');
//全部替换
var str = 'abcabc'
var nStr = str.replace(/a/,'哈哈')
console.log(nStr) //哈哈bcabc
console.log('---------------------------');
//全部替换g
var nStr = str.replace(/a/g,'哈哈')
console.log(nStr) //哈哈bc哈哈bc
//忽略大小写i
var str = 'aAbcAba';
var newStr = str.replace(/a/gi,'哈哈')//"哈哈哈哈bc哈哈b哈哈"

5、正则替换敏感词

html 复制代码
<textarea name="" id="message"></textarea> <button>提交</button>
<div></div>
<script>
    var text = document.querySelector('textarea');
    var btn = document.querySelector('button');
    var div = document.querySelector('div');
    btn.onclick = function() {
    	div.innerHTML = text.value.replace(/激情|gay/g, '**');
    }
</script>

正则特殊字符大全(MDN)

断言

表示一个匹配在某些条件下发生。断言包含先行断言、后行断言和条件表达式。

字符类

区分不同类型的字符,例如区分字母和数字。

组和范围

表示表达式字符的分组和范围。

量词

表示匹配的字符或表达式的数量。

Unicode字符类转义

基于 unicode 字符属性区分字符。例如大写和小写字母、数学符号和标点。

正则表达式的特殊字符,参考链接:正则表达式

如果大家不理解的正则表达式,可以使用正则表达式可视化工具,这里推荐一个英文简约版:

Regex for playground - IHateRegex

以及中文版:正则表达式解析器 | 代码生成器

相关推荐
运维小贺15 小时前
Nginx常用的模块
运维·nginx·正则表达式
Viooocc2 天前
正则表达式
正则表达式
vvilkim2 天前
开发中常用的正则表达式规则与应用
正则表达式
林深的林3 天前
正则表达式(1)
正则表达式
ThisIsClark4 天前
【玩转正则表达式】正则表达式常用语法汇总
正则表达式
ThisIsClark4 天前
【玩转正则表达式】替换与正则表达式的结合
正则表达式
浪九天4 天前
Java常用正则表达式(身份证号、邮箱、手机号)格式校验
java·开发语言·正则表达式
ThisIsClark5 天前
【玩转正则表达式】将正则表达式中的分组(group)与替换进行结合使用
数据库·mysql·正则表达式
小张-森林人7 天前
Oracle 字符串分割革命:正则表达式与 Lateral Join 的优雅解法
数据库·oracle·正则表达式
Lojarro7 天前
正则表达式
正则表达式