正则表达式

正则表达式

基础语法

没有特殊意义的字符

/ace/ // 匹配 ace
/123/ // 匹配 123
/-_-_-_/ // 匹配 -_-_-
/煜成/ // 匹配 煜成

转义字符

1

字符集和

[abc] //匹配a或b或c
[^abc] //匹配abc之外的任意字符
[0-9] //[0123456789]的缩写
[a-z] //匹配a到z内的任意字符

上图中部分转义字符与字符集的对应关系

. //匹配除了换行符(\n)以外的任意一个字符 = [^\n]
\w = [0-9a-Z_]
\W = [^0-9a-Z_]
\s = [\t\n\v]
\S = [^\t\n\v]
\d = [0-9]
\D = [^0-9]

量词

{n}匹配n次,比如a{2},匹配aa

{m, n}匹配m-n次,优先匹配n次,比如a{1,3},可以匹配aaa、aa、a

{m,}匹配m-∞次,优先匹配∞次,比如a{1,},可以匹配aaaa…

? 匹配0次或1次,优先匹配1次,相当于{0,1}

+匹配1-n次,优先匹配n次,相当于{1,}

*匹配0-n次,优先匹配n次,相当于{0,}

正则默认贪婪模式,凡是表示范围的量词,都优先匹配上限而不是下限

a{1, 3} // 匹配字符串'aaa'的话,会匹配aaa而不是a
非贪婪模式
***此处出现了?的用法
a{1, 3}? // 匹配字符串'aaa'的话,会匹配a而不是aaa

字符边界

有边界的匹配要求,比如已xxx开头,已xxx结尾

^在[]外表示匹配开头的意思

^abc // 可以匹配abc,但是不能匹配aabc

$表示匹配结尾的意思

abc$ // 可以匹配abc,但是不能匹配abcc

\b表示单词的边界

abc\b // 可以匹配 abc ,但是不能匹配 abcc

选择表达式

正则中用|来表示分组

a|b // 匹配a或者b
123|456|789 // 匹配123或456或789

分组与引用

(abc){2} // 匹配abcabc
(123|456){2} // 匹配 123123、456456、123456、456123
捕获分组和非捕获分组

分组默认都是捕获的,在分组的(后面添加?:可以让分组变为非捕获分组,非捕获分组可以提高性能和简化逻辑

***此处出现了?的用法
'123'.match(/(?:123)/) // 返回 ['123']
'123'.match(/(123)/)  // 返回 ['123', '123']
引用

比如在匹配html标签时,通常希望后面的xxx能够和前面保持一致

引用的语法是\数字,数字代表引用前面第几个捕获分组,注意非捕获分组不能被引用

<([a-z]+)><\/\1> // 可以匹配 `<span></span>` 或 `<div></div>`等

预搜索

***此处出现了?的用法
//前瞻?=
exp1(?=exp2) //匹配到后面是exp2的exp1
//负前瞻?!
exp1(?!exp2) //匹配到后面不是exp2的exp1
//后顾?<=
(?<=exp2)exp1 //匹配到前面是exp2的exp1
//负后顾
(?<!exp2)exp1 //匹配到前面不是exp2的exp1

例子:

"奶油巧克力".replace(/(?<=奶油)巧克力/, "蛋糕") //"奶油蛋糕"
"榛子巧克力".replace(/(?<=奶油)巧克力/, "蛋糕") //"榛子巧克力",没匹配到

正则表达式中的?=、?!、?<=、?<!、?:

()表示捕获分组,()会把每个分组里的匹配的值保存起来,使用$n(n是一个数字,表示第n个捕获组的内容)
(?:)表示非捕获分组,和捕获分组唯一的区别在于,非捕获分组匹配的值不会保存起来

例子:

// 数字格式化 1,234,567,890
"1234567890".replace(/\B(?=(?:\d{3})+$/,",");
// 结果:1,234,567,890
//查找\B (单词边界),然后把\B替换成 "," 相当于在两个相邻的数字之间添加一个","

修饰符

默认正则是区分大小写

/xxx/gi // 最后面的g和i就是两个修饰符

g正则默认遇到第一个匹配的字符就会结束,加上全局修饰符g,可以让其匹配到结束

i正则默认是区分大小写的,i可以忽略大小写

m正则默认遇到换行符就结束了,不能匹配多行文本,m可以让其匹配多行文本

例子

/^[a-z]*[^\d]{1,10}?(aaa|bbb)(?:ccc)$/

2

RegExp图形化展示的工具

使用正则

创建正则

两种方法:字面量和new

var reg = /abc/g // 字面量
var reg = new RegExp('abc', 'g') // new方式

API

js中用到正则的地方有两个入口,正则的api和字符串的api,RegExp#test等于RegExp.prototype.test

RegExp#test

RegExp#exec

String#search

String#match

String#split

String#replace

RegExp#test

每个正则实例都有test方法,test的参数是字符串,返回值是布尔值,表示当前正则是否能匹配指定的字符串

/abc/.test('abc') // true
/abc/.test('abd') // false
RegExp#exec

exec使用方法和test一样,只是返回值并不是布尔值,而是返回匹配的结果

匹配成功返回一个数组,数组第一项是匹配结果,接着是捕获的分组,index表示匹配成功的序列在输入字符串中的索引位置,input是输入的字符串

/abc(d)/.exec('abcd') // ["abcd", "d", index: 0, input: "abcd"]

如果有全局参数(g),第二次匹配时将从上次匹配结束时继续

var r1 = /ab/
r1.exec('ababab') // ['ab', index: 0]
r1.exec('ababab') // ['ab', index: 0]

var r2 = /ab/g
r2.exec('ababab') // ['ab', index: 0]
r2.exec('ababab') // ['ab', index: 2]
r2.exec('ababab') // ['ab', index: 4]

如果匹配失败则返回null

/abc(d)/.exec('abc') // null

这一特性可以被用于循环匹配,比如统计字符串中abc的次数

var reg = /abc/g
var str = 'abcabcabcabcabc'
var num = 0;
var match = null;
while((match = reg.exec(str)) !== null) {
    num++
}
console.log(num) // 5
String#match

match方法也会返回匹配的结果,匹配结果和exec类似

'abc'.match(/abc/) // ['abc', index: 0, input: abc]
'abc'.match(/abd/) // null

如果有全局参数(g),match会返回所有的结果,并且没有index和input属性

'abcabcabc'.match(/abc/g) // ['abc', 'abc', 'abc']
String#search

search方法返回匹配成功位置的索引,参数是字符串或正则,结果是索引

'abc'.search(/abc/) // 0
'abc'.search(/c/) // 2

如果匹配失败则返回-1

'abc'.search(/d/) // -1
String#split

字符串的split方法,可以用指定符号分隔字符串,并返回数据

'a,b,c'.split(',') // [a, b, c]

其参数也可以使一个正则,如果分隔符有多个时,就必须使用正则

'a,b.c'.split(/,|\./) // [a, b, c]
String#replace

字符串的replace方法,可以将字符串的匹配字符,替换成另外的指定字符

'abc'.replace('a', 'b') // 'bbc'

其第一个参数可以是正则表达式,如果想全局替换需添加全局参数

'abc'.replace(/[abc]/, 'y') // ybc
'abc'.replace(/[abc]/g, 'y') // yyy 全局替换

在第二个参数中,也可以引用前面匹配的结果

'abc'.replace(/a/, '$&b') // abbc $& 引用前面的匹配字符
'abc'.replace(/(a)b/, '$1a') // aac &n 引用前面匹配字符的分组
'abc'.replace(/b/, '$\'') // aac $` 引用匹配字符前面的字符
'abc'.replace(/b/, "$'") // acc $' 引用匹配字符后面的字符

replace的第二个参数也可以是函数,其第一个参数是匹配内容,后面的参数是匹配的分组

'abc'.replace(/\w/g, function (match, $1, $2) {
    return match + '-'
})
// a-b-c-

去除字符串前后空白

str = str.replace(/^\s*|\s*$/g, '')

RegExp

RegExp是一个全局函数,可以用来创建动态正则,其自身也有一些属性

  • $_
  • $n
  • input
  • length
  • lastMatch
/a(b)/.exec('abc') // ["ab", "b", index: 0, input: "abc"]

RegExp.$_ // abc 上一次匹配的字符串
RegExp.$1 // b 上一次匹配的捕获分组
RegExp.input // abc 上一次匹配的字符串
RegExp.lastMatch // ab 上一次匹配成功的字符
RegExp.length // 2 上一次匹配的数组长度

实例属性

正则表达式实例的一些属性

  • flags
  • ignoreCase
  • global
  • multiline
  • source
  • lastIndex 表示上次匹配成功后的索引

还是看例子

var r = /abc/igm;

r.flags // igm
r.ignoreCase // true
r.global // true
r.multiline // true
r.source // abc

r.exec('abcabcabc') // ["abc", index: 0]
r.lastIndex // 3

r.exec('abcabcabc') // ["abc", index: 3]
r.lastIndex // 6

//可以更改lastIndex让其重新开始
r.lastIndex = 0
r.exec('abcabcabc') // ["abc", index: 0]

例子

/(?:0\d{2,3}-)?\d{7}/ // 电话号 010-xxx xxx

/^1[378]\d{9}$/ // 手机号 13xxx 17xxx 18xxx

/^[0-9a-zA-Z_]+@[0-9a-zA-Z]+\.[z-z]+$/ // 邮箱
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值