正则表达式(regular expression)是一种表达文本模式(即字符串结构)的方法,有点像字符串的模板,常常用来按照“给定模式”匹配文本…

一、基础语法

新建正则表达式有两种方法:

  • 使用字面量,以斜杠/表示开始和结束
  • 使用RegExp构造函数
// 在引擎编译代码时,就会新建正则表达式
// 效率较高、比较便利和直观。实际应用中,基本都采用这种方式
const regex = /xyz/i;

// 运行时新建正则表达式
const regex = new RegExp('xyz', 'i');

第二个参数i,表示修饰符

  • i: 忽略大小写
  • g: 全局匹配(global
  • m: 多行模式,会修改^$的行为。默认情况下,^$匹配字符串的开始处和结尾处,加上m修饰符以后,^$会识别换行符\n匹配行首和行尾
const reg = /world$/
const reg1 = /world$/m
const str = 'hello world\n'

reg.test(str) // false
reg1.test(str) // true

1. 实例方法

  • test()返回一个布尔值,表示当前模式是否能匹配参数字符串
  • exec()用来返回匹配结果。匹配则返回一个数组,成员是匹配成功的子字符串,否则返回null
var s = '_x_x';
var r1 = /x/;
var r2 = /y/;

r1.test(s) // true
r1.exec(s) // ["x"]
r2.exec(s) // null

2. 字符串的实例方法

String.prototype.match(): 对字符串进行正则匹配,返回匹配结果

  • 与正则对象的exec()类似:匹配成功返回一个数组,匹配失败返回null
  • 带有g修饰符,则与正则对象的exec()行为不同,会一次性返回所有匹配成功的结果
const reg = /x/g;
const reg1 = /x/;
const reg2 = /y/;
const str1 = '_x_x';
const str2 = 'abba';

str1.match(reg1) // ["x"]
str1.match(reg2) // null
str1.match(reg) // ["x", "x"]
reg1.exec(str1) // ["x"]

3. 匹配规则

  1. “字面量字符”: 正则表达式中,某个字符只表示它字面的含义(就像下面的a和b)

比如/a/匹配a,/b/匹配b

  1. 元字符:除字面量字符外,还有一部分字符不代表字面的意思,有特殊含义
  • 点字符.: 匹配除回车\r、换行\n 、行分隔符\u2028和段分隔符\u2029以外的所有字符
  • 位置字符: ^ 表示字符串的开始位置,$表示字符串的结束位置
  • 选择符: | 表示“或关系”(OR)
  • 量词符?: 某个模式出现0次或1次,等同于{0, 1}
  • 量词符\*: 某个模式出现0次或多次,等同于{0,}
  • 量词符+: 某个模式出现1次或多次,等同于{1,}
  • 捕获符()
const reg = /(.)b(.)/g;
reg.test('dbc') // true
reg.test('db') // false

'abcdba'.match(reg) // ['abc', 'dba']
  • []: 字符集:连字符-和脱字符^
// [] 匹配这个集合中的任一一个字符(或元字符) 
// 脱字符`^`: 方括号内的第一个字符是`[^]`,则表示除了字符类之中的字符,其他字符都可以匹配
// 连字符`-`: 方括号内连续序列的字符,连字符`[-]`用来提供简写形式

const reg = /[^abc]/
const reg1 = /[abc]/

reg.test('hello world') // true
reg.test('bbc') // false
reg1.test('ade') // true
reg1.test('def') // false

[0-9a-fA-F]
[a-zA-Z0-9_-] // 是指大小写字母、数字、下划线、横线中的一个字符
  • 精确匹配次数{}
    • {n} 精确匹配n次
    • {n,} 匹配n次以上
    • {n,m} 匹配n-m次
  1. 转义符: 如果要匹配特殊含义的元字符本身,需要在它们前面要加上反斜杠。比如要匹配+,就要写成\+
/1+1/.test('1+1') // false
/1\+1/.test('1+1') // true
  1. 特殊字符 正则表达式对一些不能打印的特殊字符,提供了表达方法。
  • \cX 表示Ctrl-[X],其中的X是A-Z之中任一个英文字母,用来匹配控制字符
  • [\b] 匹配退格键(U+0008),不要与\b混淆
  • \n 匹配换行键
  • \r 匹配回车键
  • \t 匹配制表符 tab(U+0009)
  • \v 匹配垂直制表符(U+000B)
  • \f 匹配换页符(U+000C)
  • \0 匹配null字符(U+0000)
  • \xhh 匹配一个以两位十六进制数\x00-\xFF表示的字符
  • \uhhhh 匹配一个以四位十六进制数\u0000-\uFFFF表示的 Unicode 字符
  1. 预定义模式
  • \d 匹配0-9之间的任一数字,相当于[0-9]
  • \D 匹配所有0-9以外的字符,相当于[^0-9]
  • \w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]
  • \W 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]
  • \s 匹配空格(包括换行符、制表符、空格符等),相等于[ \t\r\n\v\f]
  • \S 匹配非空格的字符,相当于[^ \t\r\n\v\f]
  • \b 匹配词的边界
  • \B 匹配非词边界,即在词的内部
const reg = /a\b/
const reg1 = /a\B/
const str = 'abcdef'

reg.test(str) // false
reg1.test(str) // true

二、常用示例

// 非空 `/\S/`

1.版本号

// 验证版本号的正则表达式,适配:x.x.x、x.x.x-beta.x、x.x.x-alpha.x格式
let reg = /^\d+(\.\d+){2}(-([a-z]+)\.\d+)?$/i
reg.test("1.2.15-beta.15") // true

// 1.\d+ 匹配一个或多个数字
// 2.(\.\d+){2} 匹配点号和一个或多个数字,重复2次
// 3.(-([a-z]+)\.\d+)? 匹配可选的 - 开头的字符串和一个或多个小写字母和点号,以及一个或多个数字,例如 -beta.1、 -alpha.2 等
// 4.$ 匹配字符串的结束位置。^ 匹配字符串的开始位置
// 5./i 表示不区分大小写,即忽略 -beta 或 -Beta 的大小写差异

若需满足每位版本号不能以0开头,且不能全部为0的要求,则需要自行拓展

2.字符串: 模版渲染

// 1.利用非贪婪匹配 /\{\{(.*?)\}\}/g 匹配到到所有的 {{name}},{{age}}
// 2.利用str.replace(regexp|substr, newSubStr|function) ,其中第二个参数是 fucntion (replacement) ,该函数的返回值将替换掉第一个参数匹配到的结果,将所有匹配到的字符替换成指定的字符
var template = "{{name}}很厉害,才{{age}}岁"
var context = {name:"bottle",age:"15"}
function render(template, context) {
  return template.replace(/{{(.*?)}}/g, (match, key) => context[key.trim()])
}
console.log(render(template, context)); // "bottle很厉害,才15岁"

参考


最后, 希望大家早日实现:成为编程高手的伟大梦想!
欢迎交流~

微信公众号

本文版权归原作者曜灵所有!未经允许,严禁转载!对非法转载者, 原作者保留采用法律手段追究的权利!
若需转载,请联系微信公众号:连先生有猫病,可获取作者联系方式!