正则表达式
什么是正则表达式
由普通字符和特殊字符组成的文字模式
创建正则表达式的两种方式
字面量或直接量方式
/regular expression/
构造函数方式
new RegExp()
//demo
var str = 'i miss u';
var pattern = /miss/;
console.log(pattern.test(str)); //返回true/false
console.log(pattern.exec(str)); //返回一个数组/null
修饰符
- i : ignoreCase,忽略大小写
- g : global,全局匹配
- m : multiline,多行匹配
var str = 'i miss u';
var pattern = /MISS/i;
console.log(pattern.test(str)); //true
console.log(pattern.exec(str)); //["miss",index:2,input:"i miss u",length:1];
var str = 'i miss u';
var pattern = new RegExp('MISS','i');
console.log(pattern.test(str)); //返回true/false
console.log(pattern.exec(str)); //返回一个数组/null
使用哪种方式创建正则?
构造函数创建正则比较笨重,但是它的好处在于它能够传入变量
var str = 'i love Js';
var userInput = 'love';
var pattern = new RegExp(userInput,'i');
console.log(pattern.test(str))
转义字符
//转义 '/'
var str = '//123456789';
var pattern = /\/\//;
console.log(pattern.exec(str));
//转义tab
var str = ' t';
var pattern = /\t/;
console.log(pattern.exec(str));
//unicode
var str = ' t';
var pattern = /\u0009/;
console.log(pattern.exec(str));
中文unicode范围是\u4e00-\u9fa5
字符类
- []
var str = 'javascript';
var pattern = /[as]/; //只取一个字符,如果我匹配到了'j',这个正则就算是匹配过了,
console.log(pattern.exec(str)); //a
- ^
var str = 'javascript';
var pattern = /[^ajs]/; //取反,除了ajs以外的所有字符
console.log(pattern.exec(str)); //v
- a-z
var str = 'javascript';
var pattern = /[a-zA-Z]/; //a-z范围
console.log(pattern.exec(str)); //j
//匹配汉字
var str = 'greentea帅';
var pattern = /[\u4e00-\u9fa5]/;
console.log(pattern.exec(str));
- .
var str = '3.1415926';
var pattern = /./; //匹配除了'\n'以外的所有字符
console.log(pattern.exec(str));
- \w
取反: \W
var str = '_';
var pattern = /./; //匹配a-zA-Z0-9_
console.log(pattern.exec(str)); //_
- \d
取反:\D
var str = '962464';
var pattern = /\d/; //匹配0-9
console.log(pattern.exec(str)); //9
- \s
取反:\S
var str = ' ';
var pattern = /\s/; //匹配空格和制表符
console.log(pattern.exec(str)); //' '
重复
var str = '110123';
var pattern = /\d{2,4}/; //匹配2-3个
var pattern = /\d{2,}/; //至少匹配两个
var pattern = /\d{2}/; //匹配两个
var pattern = /\d?/ //{0,1}
var pattern = /\d+/ //{1,}
var pattern = /\d*/ //{0,}
console.log(pattern.exec(str)); //1101
//demo
var price = "iphone价格7888.8";
var pattern = /\d+\.?\d*/
console.log(pattern.exec(price)); //7888.8
非贪婪的重复
正则在默认的情况下都是贪婪的
在这个demo中,正则a查找一个或多个,但是它却匹配了最多的情况:
//demo
var str = 'aaaac';
var pattern = /a+/;
console.log(pattern.exec(str)); //aaaa
如果想按照最小来匹配呢?
在量词后加'?'转换为非贪婪匹配
var str = 'aaaac';
var pattern = /a+?/;
console.log(pattern.exec(str)); //a
再看一种情况:
var str = 'aaaac';
var pattern = /a+?c/;
console.log(pattern.exec(str)); //aaaac
在这里,为什么不是'ac'而是'aaac'?因为正则表达式中匹配是从第一个位子匹配开始的,不一定找最合适的,而是最先能够匹配的
选择
var str = 'css html js';
var pattern = /html|css|js/; //或者的意思
console.log(pattern.exec(str)); //css
分组和引用
我们想匹配'abab',但是却只匹配了'ab',因为量词影响的是'b',而不是'ab'
//demo
var str = 'abab';
var pattern = /ab+/;
console.log(pattern.exec(str)); //ab
因此,用到了分组
var str = 'abab';
var pattern = /(ab)+/;
console.log(pattern.exec(str)); //abab
此时影响的就是'ab'了
再看一个关于'()'的例子:
var str = 'abcd';
var pattern = /(ab)c/;
console.log(pattern.exec(str)); //['abc','ab']
此时,它不仅会匹配'abc',还会匹配'ab',这个'ab'是捕获来的,如果我们不想捕获它,可以这样:
var str = 'abcd';
var pattern = /(?:ab)c/;
console.log(pattern.exec(str)); //['abc']
此时,我们匹配的就只有'abc'了
再看一个关于捕获的例子
var str = 'abcd';
var pattern = /(a(b(c))/;
console.log(pattern.exec(str)); //['abc','abc','bc','c']
还有一个....
var str = 'ab cd ab';
var pattern = /(ab) cd \1/; //代表第一个分组
console.log(pattern.exec(str)); //['ab cd ab','ab'];
关于引用,我们可以做到前面和后面是相同的,例如:
var str = '';
var pattern = /<([a-zA-Z]+)>(.*?)<\/\1>/;
console.log(pattern.exec(str)); //["", "p", "这是一段文字"]
位置匹配值收尾匹配
var str = 'js';
var pattern = /^js$/; //里面的'j'必须是开头,'s'必须是结尾
console.log(pattern.exec(str)); //js
举个例子,如何保证输入的都是数字?
var str = '0982304985935309840958';
var pattern = /^\d+$/; //
console.log(pattern.exec(str)); //0982304985935309840958
是不是so easy?
关于边界匹配:
var str = 'js html';
var pattern = /js\b/; // '\b'为匹配边界
console.log(pattern.exec(str)); //js
RegExp对象的实例方法
var str = 'js js js';
var pattern = /js/g; //全局匹配
console.log(pattern.exec(str)); //js
console.log(pattern.exec(str)); //js
console.log(pattern.exec(str)); //js
console.log(pattern.exec(str)); //null
RegExp对象的实例属性
var str = 'js js js';
var pattern = /js/ig;
console.log(pattern.ignoreCase); //true
console.log(pattern.global); //true
console.log(pattern.multiline); //false
lastIndex
var str = 'js js js';
var pattern = /js/ig;
console.log(pattern.lastIndex); //0
pattern.test(str);
console.log(pattern.lastIndex); //2
pattern.test(str);
console.log(pattern.lastIndex); //5
pattern.test(str);
console.log(pattern.lastIndex); //8
pattern.test(str);
console.log(pattern.lastIndex); //0
String对象中与正则表达式相关的方法
search
查找匹配到的位置,没有匹配到返回-1,有没有全局
g
都是无所谓的,本来我就是用来查找是否存在的
var str = 'html js';
var pattern = /js/;
console.log(str.search(pattern)); //5
也可以使用字符串,但是如果使用字符串还是会将字符串转为正则
var str = 'html js js';
console.log(str.search('js'));
match
match 在费全局的情况下才会返回分组中匹配到的内容,全局匹配只能匹配到所有匹配到的字符
exec 无论是否全局匹配都会返回分组中匹配到的内容,都只会返回当前匹配到的一个内容,而不是全部返回
var str = 'js js js';
var pattern = /js/g;
console.log(str.match(pattern)); //[js,js,js]
var str = '1.js\n2.js\n3.js';
var pattern = /js$/mg; //多行匹配要和全局匹配与(首)尾匹配要联合起来使用
console.log(str.match(pattern));
var str = 'html,css,js';
console.log(str.split(',')); //[html,css,js]
split
var str = 'html , css , js';
var pattern = /\s*,\s*/;
console.log(str.split(pattern));
replace
var str = 'i love js js';
var pattern = /js/g;
console.log(str.replace(pattern,'html')); //i love html html