正则表达式就是一种表达文本模式(即字符串结构)的方法,有点像字符串的模板,常常用来按照“给定模式”匹配文本
简而言之就是是一种模板,用这个模板来匹配字符串
使用字面量
var reg = /xy/igm;
xy表示要匹配的字符串
igm是修饰符,意思分别是
i ---- ignoreCase 忽略大小写
g ----global 全局匹配
m ---- multiline 多行匹配
使用RegExp()构造函数
var reg = new RegExp(‘xy’,‘igm’);
两种方式是一样的,区别是 字面量的方式在编译时创建表达式,构造函数是在运行时创建表达式,因此字面量的效率高一些,建议使用字面量
var regex = /xy/ig;
// 等同于
// var regex = new RegExp('xy','ig');
// !!!!实例属性
// 1.修饰符相关 只读
// true 正则表达式是否设置了 i 属性
console.log('regex.ignoreCase',regex.ignoreCase);
// true 正则表达式是否设置了 g 属性
console.log('regex.global',regex.global);
// false 正则表达式是否设置了 m 属性
console.log('regex.multiline',regex.multiline);
// 正则表达式的所有已设置的属性,按字母排序
console.log('regex.flags',regex.flags);
// 2.修饰符无关
// 0 下次搜索开始的位置 可读写 lastIndex下一次开始搜索的位置
console.log('regex.lastIndex',regex.lastIndex);
// 'xy',string source 返回正则表达式的字符串形式,不包括 反斜杠,只读
console.log('regex.source,typeof regex.source',regex.source,typeof regex.source);
//!!!!实例方法
// test()检查字符串里是否有满足正则表达式的字符串,返回值是 true/false
// ture
console.log('test()',/cat/.test('cats and dogs'));
// 正则表达式为空,则匹配所有字符串
// true
console.log('new RegExp("")',new RegExp('').test('this is a test'));
// exec()返回的是符合 正则表达式的字符串 数组,否则返回 null
// index 整个模式首先匹配成功的开始位置
// input 原字符串
// ['cat']
var reg = /cat/ig;
console.log('exec()',reg.exec('cat and bat and Cat'));
// ['Cat'] 使用了 g ,记录了上次匹配结束的位置
// 当匹配结果为 null 时,下一次匹配会重头开始 ,lastIndex 会重置为0
console.log(reg.exec('cat and bat and Cat'));
// !!!! 字符串中关于正则表达式的实例方法
// match() 返回的是数组,成员是所有匹配的子字符串,否则返回null,与 exec() 类似
// 不同: 当含有 g 修饰符时,返回的是所有匹配的子字符串,每次匹配都是从头开始
// ['cat']
console.log('match()','cat and bat and Cat'.match(/cat/ig));
// search() 返回的是整数,表示第一个匹配开始的位置,否则返回 -1
// 0
console.log('search()','cat and bat and Cat'.search(/cat/));
// repalce() 返回的是替换后的字符串 ,参数1 是需要替换的内容, 参数2 是替换的内容
// dog and bat and Cat
console.log('replace()','cat and bat and Cat'.replace(/cat/,'dog'));
// dog and bat and dog
console.log('replace()','cat and bat and Cat'.replace(/cat/ig,'dog'));
// split() 以分隔符返回分隔字符串后的数组
// 正则默认是贪婪匹配
// [ "c", "t ", "nd b", "t ", "nd C", "t" ]
console.log('split()','cat and bat and Cat'.split(/a/));
// [ "c", "a", "t ", "a", "nd b", "a", "t ", "a", "nd C", "a","t"]
// 如果正则表达式里有 括号 ,则括号里匹配的内容也会返回
console.log('split()','cat and bat and Cat'.split(/(a)/));
字面量字符,字符就是它本身没有其他含义
元字符,有特殊含义的字符
// [ "cat", "cbt", "cct", "c t", "c=t" ]
console.log('点字符','cat cbt cct cddt c t c=t'.match(/c.t/g));
// ["cddt"]
console.log('两个点字符','cat cbt cct cddt c t c=t'.match(/c..t/g))
// null
console.log('^ match()','at cbt cct cddt c t c=t'.match(/^cat/));
// true
console.log('^ test()',/^cat/.test('cat cbt cct cddt c t c=t'));
// ["c=t"]
console.log('$ match','cat cbt cct cddt c t c=t'.match('c=t$'));
// true
console.log('$ test()',/c=t$/.test('cat cbt cct cddt c t c=t'));
// true /^cat$/表示字符串只能是 cat
console.log("^ $",/^cat$/.test('cat'));
// false
console.log("^ $",/^cat$/.test('cat cat'));
选择符(|)
或关系,匹配其中一个, | 会匹配前后的多个字符,要想只匹配指定的字符个数可以使用 圆括号
比如/ab|cd/指的是匹配ab或者cd,而不是指匹配b或者c。如果想修改这个行为,可以使用圆括号。
/a( |\t)b/.test(‘a\tb’) true 代码指的是,a和b之间有一个空格或者一个制表符。
转义符(\)
有特殊含义的字符想要匹配自身时必须使用转义字符
正则表达式中需要转义的字符有12个 ^ $ . ( ) [ | * + ? {
注意 使用RegExp函数生成正则表达式时,需要加 两个斜杠, 因为字符串内部会先转义一次
// 报错 missing ) after argument list
// console.log('\',new RegExp('1\.1').test('1.1'));
// true
console.log('RegExp',new RegExp('1\\.1').test('1.1'));
// false 字符串中没有 abc 的任意一个
console.log('字符类 test()',/[abc]/.test('ddddddddddddd'));
// true 字符串中出现了 a
console.log('字符类 test()',/[abc]/.test('adddddddddddd'));
// 6.1 脱字符 (^ 只有在字符类的第一个位置才有特殊含义)
// [^] 表示除了 字符类之外的其他字符都可以匹配,包括换行符 例如[^xyz]表示除了 x,y,z 剩下的都可以匹配
// true
console.log('[^]',/[^cat]/.test('cat bdefghijklmnopqrsuvwxyz'));
// false 除了 cat 在没其他字符因此 false
console.log('[^]',/[^cat]/.test('catcatcatcatcatatatcatat'));
// 换行符
// false 点字符不能匹配换行符
console.log('换行符使用 . 匹配',/good.*day/.test('today is a good\n day'));
// true [^]可以匹配换行符
console.log('换行符使用 [^] 匹配',/good[^]*day/.test('today is a good\n day'));
// 6.2 连字符(-)
// 连续序列的字符 的简写,只包含前后的一个字符 如 [1-9] 表示1,2,3...9
// false
console.log('-不在[]里',/a-c/.test('abc'));
// true
console.log('-在[]里',/[a-c]/.test('abc'));
// 注意 [1-31] 表示 1-3
// \b 的例子
/\bworld/.test('hello world') // true
/\bworld/.test('hello-world') // true
/\bworld/.test('helloworld') // false
// \B 的例子
/\Bworld/.test('hello-world') // false
/\Bworld/.test('helloworld') // true
// 指定 c 出现 2~6 次
console.log('{n,m}',/abc{2,6}d/.test('abcccdd'));
// [ "aaaaaa" ]
console.log('贪婪模式',/a*/.exec('aaaaaab'));
// 改 为非贪婪模式
// ?? 匹配 0 或 1,采用非贪婪模式
// *? 匹配 0 或 多,采用非贪婪模式
// +? 匹配 1 或 多,采用非贪婪模式
// [ "" ]
console.log('?? 非贪婪模式',/a??/.exec('aaaaaab'));
// [ "" ]
console.log('*? 非贪婪模式',/a*?/.exec('aaaaaab'));
// [ "a" ]
console.log('+? 非贪婪模式',/a+?/.exec('aaaaaab'));
// true \1匹配的是 a \2匹配的是 c
console.log('组匹配里 \n',/(.)b(.)\1b\2/.test('abcabc'));
// [ "abcabc", "abc" ]
console.log('非捕获组','abcabc'.match(/(abc){1,2}/));
// [ "abcabc" ]
console.log('非捕获组','abcabc'.match(/(?:abc){1,2}/))
// null
console.log('先行断言','a不在c的前面','abc'.match(/a(?=c)/));
// [ "a" ]
console.log('先行断言','a在c的前面','ac'.match(/a(?=c)/));
// null
console.log('先行否定断言','a在c的前面','ac'.match(/a(?!c)/));
// [ "a" ]
console.log('先行否定断言','a不在c的前面','bca'.match(/a(?!c)/));