想看看模板编译这块,想看看vue源码的的时候,发现开头就是一大堆正则,各种匹配,这都匹配个啥啊,无奈,只能翻了翻已经长毛了的正则小册子挨个对了…
创建正则的方式
字面量创建
字面量创建的方式是使用/ /包裹,也是使用最多的方式了吧,就是不能在里面使用变量
let reg = 'www.selfimpr.com'
console.log(/e/.test(reg)) //true
//如果是使用变量的话
let a = 'u'
console.log(/a/.test(reg)) //false
对象创建
new RegExp的方式,当正则需要动态创建的时候可以使用这种方式
let text = 'www.selfimpr.com';
let web = 'selfimpr';
let reg = new RegExp(web)
console.log(reg.test(text)) //true
正则方法和字符方法
先看一下字符串提供的支持正则表达式的方法和一些正则方法,了解这些方法才知道正则有什么用 匹配出来的结果是什么
正则方法
- RegExp.prototype.test():执行一个检索,用来查看正则表达式与指定的字符串是否匹配,返回一个true或者是false,语法是regexObj.test(str),参数是用来与正则表达式匹配的字符串
- RegExp.prototype.exec(): 在一个指定字符串中执行一个搜索匹配,返回一个数组或者是null regexObj.exec(str) 参数是用来与正则表达式匹配的字符串,可以循环调用直到所有的都匹配完
//test
let text = 'www.selfimpr.com';
console.log(/s/.test(text)) //true
//exec
const regex1 = RegExp('foo*', 'g');
const str1 = 'table football, foosball';
let array1;
while ((array1 = regex1.exec(str1)) !== null) {
console.log(`Found ${array1[0]}. Next starts at ${regex1.lastIndex}.`);
//Found foo. Next starts at 9.
//Found foo. Next starts at 19.
}
字符方法
- String.prototype.search():执行正则表达式与string之间的一个正则匹配,返回一个索引str.search(regexp)参数可以是字符串也可以是正则,找不到返回
- String.prototype.match():返回字符串与正则表达式匹配的结果,如果正则没加g修饰符,返回详细信息,加g不会返回详细的
- String.prototype.matchAll(): 返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器。str.matchAll(regexp)
- String.prototype.split():使用指定的分隔符字符串将一个String对象分割成子字符串数组,以一个指定的分割字串来决定每个拆分的位置 str.split([separator[, limit]]) separator每个拆分的字符 可以是正则,limit一个整数,限定返回的分割片段数量
- String.prototype.replace() 可以执行基本字符替换,也可以进行正则替换 str.replace(regexp|substr, newSubStr|function) regexp被替换的正则匹配的内容,substr被替换的字符 newSubStr用于替换的字符,function 用来创建新子字符串的函数,该函数的返回值将替换掉第一个参数匹配到的结果
元字符
正则表达式里面的最小字符,一次只匹配一个字符
- \d 匹配任意一个数字
- \D 除了数字以外的任意字符
- \w 任意一个字母数字下划线匹配
- \W 除了字母数字下划线的任意字符
- \s 任意一个空白字符匹配 如空格 制表符\t 换行符\n
- \S 除了空白符外的任意一个字符
- . 匹配除了换行符之外的任意字符
let str = 'selfimpr-2021 '
console.log(str.match(/\d/)) //[ '2', index: 9, input: 'selfimpr-2021', groups: undefined ]
console.log(str.match(/\D/)) //[ 's', index: 0, input: 'selfimpr-2021', groups: undefined ]
console.log(str.match(/\w/)) //[ 's', index: 0, input: 'selfimpr-2021', groups: undefined ]
console.log(str.match(/\W/)) //[ '-', index: 8, input: 'selfimpr-2021', groups: undefined ]
console.log(str.match(/\s/)) //[ ' ', index: 13, input: 'selfimpr-2021 ', groups: undefined ]
console.log(str.match(/\S/)) //[ 's', index: 0, input: 'selfimpr-2021 ', groups: undefined ]
console.log(str.match(/./)) //[ 's', index: 0, input: 'selfimpr-2021 ', groups: undefined ]
模式修饰
正则表达式在执行时会按他们的默认执行方式进行,但有时候默认的处理方式总不能满足我们的需求,所以可以使用模式修正符更改默认方式
- i 不区分大小写字母的匹配
- g 全局搜索所有匹配内容
- m 视为多行
- s 视为单行忽略换行符,使用.可以匹配所有字符
- y 从regexp.lastIndex开始匹配 默认从开头开始
- u 正确处理四个字符的utf-16编码
let str = 'selfimpr-2021'
console.log(str.match(/\d/g)) //[2 0 2 1]
console.log(str.match(/\w/i)) //[ 's', index: 0, input: 'selfimpr-2021', groups: undefined ]
console.log(str.match(/\d/y)) //null
let str = "𝒳𝒴";
console.table(str.match(/[𝒳𝒴]/u)); //结果正确 "𝒳" 否则为乱字符"�"
原子表
在一组字符中匹配某个元字符,在正则表达式中通过元字符表来完成,就是放到[] (方括号)中
- [] 只匹配其中的一个原子
- [^] 只匹配’除了’其中字符的任意一个原子
- [0-9] 匹配0到9的任意一个数字
- [a-z] 匹配小写a-z任意一个字母
- [A-Z] 匹配大写A-Z的任意一个字母
- [\d\D] [\s\S] 匹配所有
const url ='selfimpr.com'
console.log(/mr/.test(url)) //false
console.log(/[mr]/.test(url)) //true
//匹配a-f之间的任意字符
let letter = 'e'
console.log(/[a-f]/.test(letter)) //true
console.log(/[A-F]/i.test(letter)) //true
// 获取所有的用户名
let text = `
张三:010-99999999,李四:020-88888888`;
console.log(text.match(/[^:\d-,\s]+/g)) //["张三", "李四"]
原子组
如果一次要匹配多个元子的话可以用组()包裹起来,原子表的话只能匹配其中一个
//下面使用原子组匹配h1标签
const ele = `<h1>selfimpr.com</h1>`;
console.log(/<(h1)>.+<\/\1>/.test(ele)) //true
引用分组
\n指在匹配的时候使用原子组 $n指的是在替换时使用匹配的组数据
//将下面的语义标签替换成p标签
let text = `
<h1>标题一</h1>
<span>正则</span>
<h2>标题二</h2>
`;
let reg = /<(h[1-6])>([\s\S]*)<\/\1>/gi
let regText = text.replace(reg,`<p>$2</p>`)
console.log(regText)
重复匹配
如果要重复匹配一些内容的时候我们要使用重复匹配标识符
- /* 重复0次或者是更多次
- /+ 重复一次或更多次
- /? 重复0次或一次
- {n} 重复n次
- {n,} 重复n或者是更多次
- {n,m} 重复n到m次
let str = ' seeeeeee'
console.log(hd.match(/se+/i)) //seeeeeee
加一个?可以禁止贪婪,正则表达式进行重复匹配的时候默认的是贪婪匹配模式 也就是说尽量匹配更多的内容 比如*? 重复0次到任意次 尽可能少重复, +? 重复一次或多次 尽可能少重复…
其他
选择符
| 这个符号带表选择修释符,也就是 | 左右两侧有一个匹配到就可以。
字符转义
比如我们想通过正则查找/符号,但是 /在正则中有特殊的意义。如果写成///这会造成解析错误,所以要使用转义语法 ///来匹配,或者是其他的在正则中有特殊语义的字符
字符边界
^匹配字符串的开始
$匹配字符串的结束
更多的可以参考菜鸟工具…
直接上图
菜鸟工具正则表达式链接