目录
正则表达式分支: /in|(([0-9])\:(\s)[aeiou])/
正则表达式序列: (([0-9])\:(\s)([aeiou]))
正则表达式因子: [0-9]
正则表达式转义: \s
正则表达式分组: (...)
正则表达式字符集: [aeiou]
1个正则表达式分支 = 1个或多个正则表达式序列
1个正则表达式序列 = 1个或多个正则表达式因子
1个正则表达式因子 = 一个字符、一个分组、一个字符类或者一个转义序列
var regexp = /^1\d{10}$/
参数是字符串
var regexp = new RegExp(“\d{11}”, ‘g’)
参数是正则表达式
var regexp = new RegExp(/^[xyz]+/, ‘g’)
注意:如果第一个参数后面有修饰符,比如 /^[xyz]+/gi
,然后第二个参数 g
会覆盖掉前面的修饰符
问题:什么时候使用对象字面量,什么时候使用构造函数呢?
答:因为构造函数使用字符串,我们就可以插入动态的正则表达式,所以在需要根据其他来源来确定正则表达式时,使用构造函数,固定不变的使用字面量
由对象字面量或RegExp对象构建的正则表达式,都有如下属性
-
来表示范围\n
以外的所有字符[0-9]
[^0-9]
[0-9A-Za-z_]
[^0-9A-Za-z]
: 取或运算符 |
不可以单独使用
\p
,必须加描述\p{Script=Greek}
g
修饰符类似,也是全局匹配。区别是g是上次匹配之后剩余位置存在匹配就行,y要求必须从上次匹配结束位置开始进行匹配,也叫做 sticky(粘连)
匹配(可以理解为 y
修饰符隐含了头部匹配表示 ^
).
能够代表任意的单个字符(除开始符 ^、结束符 $),包括4字节的utf-16字符、行终止符行终止符:换行符、回车符、行分隔符、段分隔符
相同点:都是全局匹配
不同点:
y
每次匹配时从上次匹配结束位置匹配, g
则是每次匹配时剩余匹配字符串存在匹配则行replace
、 match
等方法,使用 g
会一次性全部匹配,使用 y
则每次匹配一轮,然后需要手动多次匹配// 针对不同点1
var s = 'aaa_aa_a';
var r1 = /a+/g;
var r2 = /a+/y;
r1.exec(s) // ["aaa"]
r2.exec(s) // ["aaa"]
r1.exec(s) // ["aa"]
r2.exec(s) // null,因为这里是以 _ 开头的
// 针对不同点2
var regg = /a/g
'aaxa'.replace(regg,'-') // '--x-'
var regy = /a/y
'aaxa'.replace(regy,'-') // '-axa'
'aaxa'.replace(regy,'-') // 'a-xa'
'aaxa'.replace(regy,'-') // 'aaxa' 就是没有替换
var reggy = /a/gy
'aaxa'.replace(reggy,'-') // '--xa'
总结:g可以用于全局匹配,但是 y 属于 伪全局匹配
, y 是粘连匹配,且需要多次手动匹配,不具备 g 完整的全局匹配
const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj.groups.year; // 1999
const month = matchObj.groups.month; // 12
const day = matchObj.groups.day; // 31
为 matchObj
增加了一个新属性 groups
/x(?=y)/
x 后面必须跟 y/(?<=x)y/
y 前必须跟 x/x(?!y)
x 后不能跟 y/(?<!x)y
y 前不能跟 x/[^\w\-]/
不能有字母、数字、-注意:分组置前时为 ?<
,置后为 ?
;非捕获型分组是 ?:
开头
(\d{11})
, 非捕获型分组: (?:(\w)*)
var number = "18224487974";
var parse_number = /^1\d{10}$/
parse_number.test(number) // true
var str = "www.baidu.com/pathname?hello=world#fragment"
var parse_url = /^(?:([a-zA-Z]*):)?(?:\/{0,3})?([0-9\.a-zA-Z]+)(?::(\d*))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:\#(.*))?$/
parse_url.exec(str) // return arr
var str = '我 you 我 he yy'
var parse_same = /([A-Za-z\u00C0-\u1FFF\u2800-\uFFFD]+)\s+/gi
console.log(parse_same.exec(str))
之前写 exec
匹配的时候,以为匹配一次就结束了。后面看到es6的y修饰符的时候,才知道匹配可以执行多次
// exec 多次匹配
var s = 'aaa_aa_a';
var r1 = /a+/g;
r1.exec(s) // ['aaa']
r1.exec(s) // ['aa']
r1.exec(s) // ['a']
r1.exec(s) // null
r1.exec(s) // ['aaa']
当正则表达式存在 g
或 y
的时候,每次执行 exec
匹配,会保存字符串上次匹配到的位置,然后下一次匹配会从上一次匹配结束的位置开始(匹配的还是原字符串,只是正则对象的 lastIndex
值变化了)。如果上一次匹配返回的结果是 null
那么下次匹配又会从头开始
如果正则表达式不存在 g
或 y
,那么它就不会多次匹配,每次匹配的时候,都是从头开始
String.prototype.replace也是可以匹配多次的
可以在第一次匹配的时候,指定
r1.lastIndex
值,表示从哪个位置开始匹配