正则表达式(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. 匹配规则
- “字面量字符”: 正则表达式中,某个字符只表示它字面的含义(就像下面的a和b)
比如
/a/匹配a,/b/匹配b
- 元字符:除字面量字符外,还有一部分字符不代表字面的意思,有特殊含义
- 点字符.: 匹配除回车\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/.test('1+1') // false
/1\+1/.test('1+1') // true
- 特殊字符 正则表达式对一些不能打印的特殊字符,提供了表达方法。
- \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 字符
- 预定义模式
- \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岁"
参考
- RegExp对象.阮一峰
最后, 希望大家早日实现:成为编程高手的伟大梦想!
欢迎交流~

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