在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要,正则表达式就是用于描述这些规则的工具。高效率的正则表达式,既能够提高程序的运行效率,也能够减少开发者的工作量。
要写好正则,这些字符必须要有所了解
^ 匹配输入字符串的开始位置
$ 匹配输入字符串的结束位置
* 匹配前面的子表达式零次或多次
+ 匹配前面的子表达式1次或多次
? 匹配前面的子表达式零次或一次
{n, m} 匹配次数n到m
. 匹配除换行符(\n、\r)之外的任何单个字符
[A-Za-z0-9_] 字符集,匹配字母、数字、下划线
\w 等价于上面的字符集
\ 转义符
() [] 圆括号和方括号,提升运算优先级
| 或运算
// 标记
i 忽略大小写
g 全局匹配
举个例子
// 全局匹配字符串是否包含abc,不区分大小写
const reg = /abc/ig
正则怎么用呢
1.test() 在字符串中查找符合正则的内容,若查找到返回true,反之返回false
function isMobile(mobile) {
const reg = /^1[0-9]{10}$/
return reg.test(mobile)
}
2.search() 在字符串搜索符合正则的内容,搜索到就返回出现的位置,如果搜索失败就返回 -1
function findIndex(str, reg) {
return str.search(reg)
}
3.match() 在字符串中搜索复合规则的内容,搜索成功就返回内容,格式为数组,失败就返回null
'haj123sdk54hask33dkhalsd879'.match(/\d+/g)
// ['123', '54', '33', '879']
4.replace() :查找符合正则的字符串,就替换成对应的字符串,返回替换后的内容
'hello zm'.replace(/zm/, 'world')
// hello world
'123'.replace(/(\d)/g, str => { return parseInt(str) * 2 })
// '246'
'123'.replace(/(\d)/g, '\\$1')
// '\1\2\3'
'15558018857'.replace(/^([\d]{3})[\d]{4}([\d]{4})$/g, '$1****$2')
// '155****8857'
5.exec() 用于正则表达式模式在字符串中运行查找,如果 exec() 找到了匹配的文本,则返回一个结果数组。否则,返回 null。除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string
/^([\d]{3})[\d]{4}([\d]{4})$/g.exec('15558018857')
// ["15558018857", "155", "8857", index: 0, input: "15558018857", groups: undefined]
这里请注意:方法234是字符串方法,方法1和5是正则方法,使用频率最高的是145
正则三段论:定锚点,去噪点,取数据
源数据:标题:深入正则表达式应用,作者:zm
需求:匹配作者名字
我要从源数据取到zm这个作者名,那么,在这里,
作者:就是我们所说的锚点,因为在上面这段数据中它能够唯一定位到我们的数据zm(就在它后面)
(1) 定锚点:作者:
而在这里,我们不需要关心标题什么的,因此,标题:深入正则表达式应用,就是我们的噪点
(2) 去噪点
最后,我们确定作者:后面就是我们的数据,这个数据可以是任意字符,因此,我们得到正则:
作者:(.*)
而噪点部分,因为不会对数据取值造成干扰,直接去掉,不需要引入正则中。
(3) 取数据
/作者:(.+)/g.exec('标题:深入正则表达式应用,作者:zm')
// ["作者:zm", "zm", index: 13, input: "标题:深入正则表达式应用,作者:zm", groups: undefined]
经典用法
// 获取url全部参数
function getQuerys(url = window.location.href) {
const reg = /([^?&#]\w+)=([^?&#]*)/ig
const querys = {}
let matchs
while( (matchs = reg.exec(url)) !== null) {
querys[matchs[1]] = matchs[2]
}
return querys
}
实现一个模版库,支持js语法
const parseHtml = (line) => {
// 单引号转义,换行符替换为空格,去掉后面的空格
line = line.replace(/('|")/g, '\\$1').replace(/\n/g, ' ').replace(/(^\s+)|(\s+$)/g,"")
return 'r.push("' + line + '");\n'
}
const parseJs = (line) => {
// 如果是js语法,则直接添加
const reExp = /(^( )?(var|if|for|else|switch|case|break|{|}|;))(.*)?/g
line = line.replace(/(^\s+)|(\s+$)/g,"")
return line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n'
}
const Tpl = (tpl, data) => {
const re = /{{(.+?)}}/g
let cursor = 0
let code = 'var r=[];\n'
let match = null
while ((match = re.exec(tpl)) !== null) {
code += parseHtml(tpl.slice(cursor, match.index))
code += parseJs(match[1])
cursor = match.index + match[0].length
}
code += parseHtml(tpl.substr(cursor, tpl.length - cursor))
code += 'return r.join("");'
return new Function(code.replace(/[\r\t\n]/g, '')).apply(data)
}
export default Tpl
// 模版
<script id="tpl" type="text/template">
<div>
<div>name: {{this.name}}</div>
{{ if(this.age) { }}
<div>age: {{this.age}}</div>
{{ } }}
<div>sex: {{ this.sex }}</div>
</div>
</script>
// 使用
Tpl(document.getElementById('tpl').innerHTML.toString(), {
name: zm,
age: 18,
sex: boy
})