正则表达式必知必会
推荐先读 正则表达式必知必会 这本书
?
放在不定量词后面(放在 * + 这样的量词后面)的? 是表示非贪婪匹配
贪婪匹配
str = "AB1111BA111BA";
reg = /AB[\s\S]+BA/;
console.log(str.match(reg));
非贪婪匹配
str = "AB1111BA111BA";
reg = /AB[\s\S]+?BA/;
console.log(str.match(reg));
放在字符后面的?表示出现0~1次
/https?/.exec('http://xxxx') 得到http
/https?/.exec('https://xxxx') 得到https
[]
[]是把多个字符定义为一个集合 表示只能出现下面字符之一
[abc] 表示这里要么a要么b要么c
同理 [img|bmp] 表示出现的字符只能是 | i m g b p 这几个字母中的一个
但是我想匹配 img 或者 bmp 则是用 |
(img|bmp) 因为|会把所在()内的所有的左边和右边都当做一个整体
当[]和? 一起用的时候 应该 []?
边界
B针对非单词的边界 /\B-\B/.exec('xcxc wd - cdsd --')
b针对单词的边界(单词: 字母 数字 下划线) /\b_\b/.exec('xcxc _ wd - cdsd --')
PS /\b-\b/.exec('xcxc _ wd - cdsd --')这样得不到结果
^ 开始和非
^ 只有在 [^....] 这样的情况下才表示非
其他的时候表示开头
例如我想匹配非b开头的房间
/\b^b\d+\b/.exec('b123 d234 s234 b4553')
["b123"]
结果不加[]反而只匹配上了b开头的房间
/\b[^b]\d+\b/.exec('b123 d234 s234 b4553')
["d234"]
一般来说 ^ 匹配开头 $匹配结尾
(?m)多行模式下 ^ $将匹配每行的开头和结尾
|
19|20\d{2} 这样并不能匹配19xx 20xx 这样的 因为|左右是一个整体
它只能匹配上 19 20xx 这样的数字
/(19|20)\d{2}/
()子表达式 捕获
()除了分组 还有个很重要的功能 它可以将子表达式的内容提取出来
()中的内容叫做子表达式
str3 = 'The s is AC/0923/d456';
str3.match(/[A-Z]{2}\/\d{4}\/[a-z]\d{3}/)
得到 ["AC/0923/d456"]
假如现在的要求是 将所有 AC/0923/d456 全部转换为 AC-0923-d456 的形式
这里就需要使用子表达式将 AC 0923 d456 分别取出来
str3.match(/([A-Z]{2})\/(\d{4})\/([a-z]\d{3})/)
["AC/0923/d456", "AC", "0923", "d456"]
这样之后就可以使用 $1 $2 $3这样的变量表达式
str3.replace(/([A-Z]{2})\/(\d{4})\/([a-z]\d{3})/, '$1-$2-$3')
"The s is AC-0923-d456"
PS $1 $2 这样的变量引用必须要有子表达式
子表达式 非捕获
(?:reg) VS (reg) 后一种就是上面说的捕获 第一种仅仅是分组但是不捕获
r1= /(\d\d\d)(.+)(\d+)/;
r2 =/(?:\d\d\d)(.+)(?:\d+)/;
str = 'm234sdvgs56'
str.match(r1)
["234sdvgs56", "234", "sdvgs5", "6"]
str.match(r2)
["234sdvgs56", "sdvgs5"]
在regexper.com看下面的分组来加深印象
/<(img|IMG).*?src=[\'\"](.*?(?:\.gif|\.jpg|\.png))[\'\"].*?[\/]?>/gi
/<(img|IMG).*?src=[\'\"](.*?(\.gif|\.jpg|\.png))[\'\"].*?[\/]?>/gi
()分组功能
/[\d]{3}-[\d]{3}-[\d]{3}-[\d]{3}/.test('333-333-222-233')
相同的部分写了好几次 实际上用()可以简写
/([\d]{3}-){3}[\d]{3}/.test('333-333-222-233')
加了gi (){} 就是分组 不获取了
match
str.match 返回一个数组
如果非全局匹配(正则中没有g) 则数组中第一个元素是第一个匹配值 之后是自表达式(捕获值)
str3 = 'The s is AC/0923/d456 BV/4641/f565';
str3.match(/([A-Z]{2})\/(\d{4})\/([a-z]\d{3})/)
["AC/0923/d456", "AC", "0923", "d456"]
全局匹配(/xxx/g) 则返回所有匹配值 木有捕获值
str3.match(/([A-Z]{2})\/(\d{4})\/([a-z]\d{3})/g)
["AC/0923/d456", "BV/4641/f565"]
假如又是全局匹配 又想得到捕获值 使用replace
str = str.replace(/.../g, function(match, p1, p2){
})
p1 p2 ... 每一次匹配中的捕获值