# 正则表达式

# 什么是正则表达式?

正则表达式(RegExp )对象用于将文本与一个 模式匹配 。其 目的 是为了字符串模式匹配,从而实现 搜索替换 功能。

# 基本组成

基本可以由 字母数字 来组成。没有特殊语义,是一一对应的关系。

TIP

如果在apple这个单词中寻找a这个字符,直接用/a/匹配这个字符即可。

# 转义符号/

转义符用于使 匹配符 失效。 举个例子,如果想匹配*这个符号, 但*本身就是个 匹配任何字符 的匹配符。这时就需要转义符/使其失去本来的作用。 /\*/

# 特殊字符表

如果本来字符不是特殊字符,使用转义符号就会让它拥有特殊的含义。我们常常需要匹配一些特殊字符,比如空格,制表符,回车,换行等, 而这些就需要我们使用转义字符来匹配。

特殊字符 正则表达式 记忆方式
换行符 \n new line
换页符 \f form feed
回车符 \r return
空白符 \s space
制表符 \t tab
垂直制表符 \v vertical tab
回退符 [\b] backspace,之所以使用[]符号是避免和\b重复

# 匹配多个字符

单个字符的映射关系是一对一,即正则表达式对应匹配的字符只有一个。若想匹配多个字符,则需要引入 集合区间和通配符 ,即可实现一对多的匹配。


在正则表达式里,集合的定义方式是使用中括号[]。如/[123]/则能同时匹配1,2,3三个字符。如果想匹配所有 数字字母 。则可以使用 元字符 - 用来表示区间范围。

TIP

匹配所有数字:/[0-9]/

匹配所有字母:/[a-z]/

# 更多的多字符匹配

同时匹配多个字符的简便正则表达式:

匹配区间 正则表达式 记忆方式
除了换行符之外的任何字符 . 句号,除了句子结束符
单个数字, [0-9] \d digit
除了[0-9] \D not digit
包括下划线在内的单个字符,[A-Za-z0-9_] \w word
非单字字符 \W not word
匹配空白字符,包括空格、制表符、换页符和换行符 \s space
匹配非空白字符 \S not space

# 元字符

# ? 0|1

元字符?代表了匹配一个字符或0个字符。设想一下,如果你要匹配colorcolour这两个单词,就需要同时保证u这个字符是否出现都能被匹配到。所以你的正则表达式应该是这样的:/colou?r/

# * >=0

元字符*用来表示匹配0个字符或无数个字符。通常用来过滤某些可有可无的字符串。

# + >=1

元字符+适用于要匹配同个字符出现1次或多次的情况。

# 特定次数

除了使用元字符在匹配项后面添加 匹配次数 ,还可以添加指定的次数

// 特定次数
const str = "hellllo"
const singleReg = /hel+o/g;
const indicatedReg = /hel{4}o/g;
console.log(str.match(singleReg)); // ['hellllo']
console.log(str.match(indicatedReg)) // ['hellllo']

# 非捕获

如果不想捕获到字符串中的某些特定字符,可使用?:xxx的方式,忽略的xxx字符。

// 非捕获
var str = 'scq000';
const covertStr = str.replace(/(scq00)(?:0)/, '$1,$2')
console.log(covertStr); // scq00,$2

# 前向查找(找前缀)

通过preStr(?=xxx),可以查找到xxx前的preStr的前缀。

// 前向查找(找前缀)
const str = `happy happily`;
const covertStr = str.match(/happ(?=ily)/)[0]; // 找 是ily的 happ前缀
console.log(covertStr); // happ

# 负前向查找(找非匹配段的前缀)

// 负前向查找(找非匹配段的前缀)
const str = `happy1 happy2 happily`;
const covertStr = str.match(/happ(?!ily)/g); // 找 不是ily的 happ前缀
console.log(covertStr); // [ 'happ', 'happ' ]

# 后向查找(找后缀)

// 后向查找(找后缀)
const str = `apple people`;
const covertStr = str.match(/(?<=ap)ple/g);
console.log(covertStr); // [ 'ple' ]

# 负后向查找(找非匹配段的后缀)

// 负后向查找(找非匹配段的后缀)
const str = `apple people niple`;
const covertStr = str.match(/(?<!ap)ple/g); // 整个单词边界匹配是两两匹配的
console.log(covertStr); // [ 'ple', 'ple' ]

# 常用的API

# Regexp.prototype.test

参数传入字符串,Reg表示 正则的格式

const Reg = /(abc)/g;
const str = 'abc';
Reg.test(str); // true

# RegExp

用于将文本与一个模式匹配,它可以两种方式创建。

  • 字面量 /ab+c/i; //字面量形式
  • 构造函数创建new RegExp('ab+c', 'i')
  • 第一位参数可以是 字符串, 也可以是 正则字面量
// 校验长度为3的字符串
const lengthReg = new RegExp(`^.{3}$`);
console.log(lengthReg.test('hhh')) // true

# Regexp.prototype.exec

exec()方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null (opens new window)

var myRe = /ab*/g;
var str = 'bbcdefbh';
var myArray;
myArray = myRe.exec(str);
console.log(myArray); // null

# String.prototype.match

match()方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null (opens new window)

var myRe = /ab*/g;
var str = 'bbcdefbh';
var myArray;
myArray = str.match(myRe);
console.log(myArray); // null

# 常用的正则表达式校验

# 1. 用户名正则

//用户名正则,4到16位(字母,数字,下划线,减号)
var uPattern = /^[a-zA-Z0-9_-]{4,16}$/;
//输出 true
console.log(uPattern.test("caibaojian"));

# 2. 密码强度正则

//密码强度正则,最少6位,包括至少1个大写字母,1个小写字母,1个数字,1个特殊字符
var pPattern = /^.*(?=.{6,})(?=.*d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$/;
//输出 true
console.log("=="+pPattern.test("caibaojian#"));

# 3. 整数正则

//正整数正则
var posPattern = /^d+$/;
//负整数正则
var negPattern = /^-d+$/;
//整数正则
var intPattern = /^-?d+$/;
//输出 true
console.log(posPattern.test("42"));
//输出 true
console.log(negPattern.test("-42"));
//输出 true
console.log(intPattern.test("-42"));

# 4. 数字正则

可以是整数也可以是浮点数

//正数正则
var posPattern = /^d*.?d+$/;
//负数正则
var negPattern = /^-d*.?d+$/;
//数字正则
var numPattern = /^-?d*.?d+$/;
console.log(posPattern.test("42.2"));
console.log(negPattern.test("-42.2"));
console.log(numPattern.test("-42.2"));

# 5. Email正则

//Email正则
var ePattern = /^([A-Za-z0-9_-.])+@([A-Za-z0-9_-.])+.([A-Za-z]{2,4})$/;
//输出 true
console.log(ePattern.test("99154507@qq.com"));

# 6. 手机号码正则

//手机号正则
var mPattern = /^1[34578]d{9}$/; //http://caibaojian.com/regexp-example.html
//输出 true
console.log(mPattern.test("15507621888"));

# 7 身份证号正则

//身份证号(18位)正则
var cP = /^[1-9]d{5}(18|19|([23]d))d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)d{3}[0-9Xx]$/;
//输出 true
console.log(cP.test("11010519880605371X"));

# 8. URL正则

//URL正则
var urlP= /^((https?|ftp|file)://)?([da-z.-]+).([a-z.]{2,6})([/w .-]*)*/?$/;
//输出 true
console.log(urlP.test("http://caibaojian.com"));

# 9 IPv4地址正则

//ipv4地址正则
var ipP = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
//输出 true
console.log(ipP.test("115.28.47.26"));

# 10. 十六进制颜色正则

//RGB Hex颜色正则
var cPattern = /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/;
//输出 true
console.log(cPattern.test("#b8b8b8"));

# 11 日期正则

//日期正则,简单判定,未做月份及日期的判定
var dP1 = /^d{4}(-)d{1,2}1d{1,2}$/;
//输出 true
console.log(dP1.test("2017-05-11"));
//输出 true
console.log(dP1.test("2017-15-11"));
//日期正则,复杂判定
var dP2 = /^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$/;
//输出 true
console.log(dP2.test("2017-02-11"));
//输出 false
console.log(dP2.test("2017-15-11"));
//输出 false
console.log(dP2.test("2017-02-29"));

# 12. QQ号码正则

//QQ号正则,5至11位
var qqPattern = /^[1-9][0-9]{4,10}$/;
//输出 true
console.log(qqPattern.test("65974040"));

# 13. 微信号正则

//微信号正则,6至20位,以字母开头,字母,数字,减号,下划线
var wxPattern = /^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$/;
//输出 true
console.log(wxPattern.test("caibaojian_com"));
# 14. 车牌号正则
//车牌号正则
var cPattern = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]{1}$/;
//输出 true
console.log(cPattern.test("粤B39006"));

# 15. 包含中文正则

//包含中文正则
var cnPattern = /[u4E00-u9FA5]/;
//输出 true
console.log(cnPattern.test("蔡宝坚"));

# 知识小结

拿字符串abc作例子

  1. /abc/ : 原义文本字符。检测字符串有没有abc
  2. /[abc]/: 字符类。 检测字符串有没有abc中的一项
  3. /[^abc]/ 反向类。 检测字符串是否有 不是abc
  4. ^写在[]里面就是反向类
  5. /^abc/: 开头边界。 检测字符串是不是a开头
  6. ^单独使用就是开头边界。注意: 边界不用检测字符串,而是检测位置的。

# 参考文章

  1. 【前端知识点总结】WebAPI 正则表达式 - 掘金 (juejin.cn) (opens new window)
  2. 正则表达式不要背 - 掘金 (juejin.cn) (opens new window)