正则表达式

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

**正则表示是用于匹配字符串中字符组合的模式。**在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

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

相关推荐
陈奕迅本讯3 天前
正则表达式
正则表达式
来恩10033 天前
C# 字符串与正则表达式介绍
数据库·正则表达式·c#
一水鉴天3 天前
为AI聊天工具添加一个知识系统 之75 详细设计之16 正则表达式 之3 正则表达式模板
人工智能·正则表达式
我不是代码教父3 天前
[原创](Modern C++)现代C++的关键性概念: 正则表达式
c++·正则表达式·子字符串
刘小炮吖i3 天前
正则表达式超详细讲解
java·正则表达式
一水鉴天5 天前
为AI聊天工具添加一个知识系统 之77 详细设计之18 正则表达式 之5
人工智能·正则表达式
兮动人8 天前
正则表达式入门
正则表达式·正则表达式入门
zfj3218 天前
java 正则表达式匹配Matcher 类
java·开发语言·正则表达式·find和matches
TPBoreas9 天前
ReUtil- 一个强大的正则表达式工具库
java·开发语言·正则表达式