正则表达式

90 阅读4分钟

1.什么是正则表达式

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

2.正则表达式的特点

灵活性、逻辑性和功能性非常的强。 可以迅速地用极简单的方式达到字符串的复杂控制。

3.创建正则表达式

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

var regexp = new RegExp(/123/);

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

var rg = /123/;

4.测试正则表达式

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

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

5.正则表达式中的特殊字符

5.1正则表达式修饰符
  • i 执行对大小写不敏感的匹配。
  • g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
  • m 执行多行匹配。
5.2正则表达式模式
  • [abc] 查找括号之间的任何字符。
  • [^abc] 查找任何不在方括号之间的字符。
  • [0-9] 查找任何从 0 至 9 的数字。
  • [^0-9] 查找任何不在括号内的字符(任何非数字)。
  • (x|y) 查找任何指定的选项。
var 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
var 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
----------------------------------------------------------------------------------
// - 短横线 表示一个范围
var 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
-----------------------------------------------------------------------------------
// 字符组合
var reg1 = /^[a-zA-Z0-9]$/; // 26个英文字母(大写和小写都可以)任何一个字母返回 true  
------------------------------------------------------------------------------------
//取反 方括号内部加上 ^ 表示取反,只要包含方括号内的字符,都返回 false 。
var 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
5.3元字符

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

  • . 查找单个字符,除了换行符或行终止符。
  • \w 查找单词字符。
  • \W 查找非单词字符。
  • \d 查找数字。
  • \D 查找非数字字符。
  • \s 查找空白字符。
  • \S 查找非空白字符。
  • \b 在单词的开头/结尾查找匹配项,开头如下:\bHI,结尾如下:HI\b。
  • \B 查找匹配项,但不在单词的开头/结尾处。
  • \0 查找 NULL 字符。
  • \n 查找换行符。
  • \f 查找换页符。
  • \r 查找回车符。
  • \t 查找制表符。
  • \v 查找垂直制表符。
  • \xxx 查找以八进制数 xxx 规定的字符。
  • \xdd 查找以十六进制数 dd 规定的字符。
  • \uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符。
var  rg1 = /\d/;
console.log(rg1.test('123456')); //true
console.log(rg1.test('abc')); //false
console.log(rg1.test('123456abc')); //true

var rg2 = /\D/;
console.log(rg2.test('123456')); //false
console.log(rg2.test('abc')); //true
console.log(rg2.test('123456abc')); //true

var rg3 = /\w/;
console.log(rg3.test('123456')); //true
console.log(rg3.test('abc')); //true
console.log(rg3.test('123456abc')); //true
console.log(rg3.test('123456abc_')); //true
console.log(rg3.test('*')); //false

var rg4 = /\W/;
console.log(rg4.test('123456')); //true
console.log(rg4.test('abc')); //true
console.log(rg4.test('123456abc')); //true
5.4量词
  • n+ 匹配任何包含至少一个 n 的字符串。
  • n* 匹配任何包含零个或多个 n 的字符串。
  • n? 匹配任何包含零个或一个 n 的字符串。
  • n{X} 匹配包含 X 个 n 的序列的字符串。
  • n{X,Y} 匹配包含 X 至 Y 个 n 的序列的字符串。
  • n{X,} 匹配包含至少 X 个 n 的序列的字符串。
  • n$ 匹配任何以 n 结尾的字符串。
  • ^n 匹配任何以 n 开头的字符串。
  • ?=n 匹配任何其后紧接指定字符串 n 的字符串。
  • ?!n 匹配任何其后没有紧接指定字符串 n 的字符串。

括号总结

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

主要记住

  • * 重复0次或更多次
  • + 重复1次或更多次
  • ? 重复0次或1次
  • {n} 重复n次
  • {n,} 重复n次或更多次
  • {n,m} 重复n到m次
// 量词符:用来设定某个模式出现的次数
//简单理解:就是让下面的a这个字符重复多少次
 
var reg = /^a$/;
 
* :相当于 >=0 可以出现0次或者很多次
var reg = /^a*$/;
console.log(reg.test(''));
console.log(reg.test('a'));
console.log(reg.test('aaaa'));
 
+ :相当于 >=1 可以出现1次或者很多次
 var reg = /^a+$/;
console.log(reg.test(''));
console.log(reg.test('a'));
console.log(reg.test('aaaa'));
 
? :相当于 1 || 0 重复1次或者0var reg = /^a?$/;
console.log(reg.test(''));
console.log(reg.test('a'));
console.log(reg.test('aaaa'));
 
{3} :就是重复3var reg = /^a{3}$/;
console.log(reg.test(''));
console.log(reg.test('a'));
console.log(reg.test('aaaa'));
console.log(reg.test('aaa'));
 
{3,}: 大于等于3 >=3
var reg = /^a{3,}$/;
console.log(reg.test(''));
console.log(reg.test('a'));
console.log(reg.test('aaaa'));
console.log(reg.test('aaa'));
 
{3,16}: 等于等于3 并且 小于等于16
var reg = /^a{3,16}$/;
console.log(reg.test(''));
console.log(reg.test('a'));
console.log(reg.test('aaaa'));
console.log(reg.test('aaa'));
5.5边界符

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

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

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

var rg = /abc/; // 正则表达式里面不需要加引号 不管是数字型还是字符串型
// /abc/ 只要包含有abc这个字符串返回的都是true
console.log(rg.test('abc'));
console.log(rg.test('abcd'));
console.log(rg.test('aabcd'));
console.log('---------------------------');
var reg = /^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

使用正则修复边界

// 使用 正则表达式边界修复错误字符串
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'(换行后)

// 2) 使用 $ 修正字符串结尾处的匹配。
buggyMultiline = buggyMultiline.replace(/aa$/gim,'ee.');
console.log(2, buggyMultiline); // 修复 'traa' => 'tree'.

// 3) 使用 \b 修正单词和空格边界上的字符。
buggyMultiline = buggyMultiline.replace(/\bi/gim,'t');
console.log(3, buggyMultiline); // 修复 'ihe' => 'the'  不影响 'light'.

// 4) 使用 \B 匹配实体边界内的字符。
fixedMultiline = buggyMultiline.replace(/\Bo/gim,'e');
console.log(4, fixedMultiline); // 修复  'greon'  不影响'on'.

6.正则表达式前瞻后顾 负前瞻和负后顾

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

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

var str= 'hello hi world';
// 前瞻 查找 e 前面的h
var pe = /h(?=e)/g;
var newStr = str.replace(pe,'T');
console.log(newStr);
6.2后顾 (后行断言)
  • (x|y) 查找任何指定的选项。
  • (?<=y)x 匹配'x'仅当'x'前面是'y'.这种叫做后行断言。例如,/(?<=Jack)Sprat/会匹配到' Sprat '仅仅当它前面是' Jack '。/(?<=Jack|Tom)Sprat/匹配‘Sprat ’仅仅当它前面是'Jack'或者是‘Tom’。但是‘Jack’和‘Tom’都不是匹配结果的一部分。

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

// 后顾 查找l后面的 d 
var pe = /(?<=l)d/g;
var newStr = str.replace(pe,'M');
console.log(newStr);

负前瞻(先行否定断言)

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

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

// 负前瞻  查找h后面不是e的  
var pe = /h(?!e)/g;
var newStr = str.replace(pe,'N');
console.log(newStr);

负后顾(后行否定断言)

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

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

// 负后顾  查找l前面不是e的
var pe = /(?<!e)l/g;
var newStr = str.replace(pe,'Q');
console.log(newStr);

7.RegExp 对象属性

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

8.RegExp 对象方法

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

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

  • search 检索与正则表达式相匹配的值。
  • match 找到一个或多个正则表达式的匹配。
  • replace 替换与正则表达式匹配的子串。
  • split 把字符串分割为字符串数组。

10.案例

10.1验证座机号码**
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
10.2表单验证案例
//手机号验证:/^1[3|4|5|7|8][0-9]{9}$/;
//验证通过与不通过更换元素的类名与元素中的内容
 if (reg.test(this.value)) {
    // console.log('正确的');
    this.nextElementSibling.className = 'success';
    this.nextElementSibling.innerHTML = '<i class="success_icon"></i> 恭喜您输入正确';
   } else {
       // console.log('不正确');
      this.nextElementSibling.className = 'error';
      this.nextElementSibling.innerHTML = '<i class="error_icon"></i>格式不正确,请从新输入 ';
 }
10.3注册页面
//QQ号验证: /^[1-9]\d{4,}$/; 
//昵称验证:/^[\u4e00-\u9fa5]{2,8}$/
//验证通过与不通过更换元素的类名与元素中的内容 ,将上一步的匹配代码进行封装,多次调用即可
 function regexp(ele, reg) {
    ele.onblur = function() {
      if (reg.test(this.value)) {
        // console.log('正确的');
        this.nextElementSibling.className = 'success';
        this.nextElementSibling.innerHTML = '<i class="success_icon"></i> 恭喜您输入正确';
   } else {
     // console.log('不正确');
     this.nextElementSibling.className = 'error';
     this.nextElementSibling.innerHTML = '<i class="error_icon"></i> 格式不正确,请从新输入 ';
            }
        }
 };
10.4正则替换replace
var str = 'andy和red';
var newStr = str.replace('andy', 'baby');
console.log(newStr)//baby和red
//等同于 此处的andy可以写在正则表达式内
var newStr2 = str.replace(/andy/, 'baby');
console.log(newStr2)//baby和red
//全部替换
var str = 'abcabc'
var nStr = str.replace(/a/,'哈哈')
console.log(nStr) //哈哈bcabc
//全部替换g
var nStr = str.replace(/a/g,'哈哈')
console.log(nStr) //哈哈bc哈哈bc
//忽略大小写i
var str = 'aAbcAba';
var newStr = str.replace(/a/gi,'哈哈')//"哈哈哈哈bc哈哈b哈哈"