正则表达式(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对象.阮一峰
最后, 希望大家早日实现:成为编程高手的伟大梦想!
欢迎交流~
本文版权归原作者曜灵所有!未经允许,严禁转载!对非法转载者, 原作者保留采用法律手段追究的权利!
若需转载,请联系微信公众号:连先生有猫病,可获取作者联系方式!