正则表达式必知必会

推荐先读 正则表达式必知必会 这本书

?

放在不定量词后面(放在 * + 这样的量词后面)的? 是表示非贪婪匹配
贪婪匹配

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 ... 每一次匹配中的捕获值

posted @ 2015-07-31 12:31  cart55free99  阅读(147)  评论(0编辑  收藏  举报