出场
为了匹配规定模式的文本
为了守护世界的和平
我们是穿梭在银河的正则表达式
就是这样~喵~
好用的正则表达式可视化工具: regexper.com/
语法
//字面量
var regExp1 = /pattern/flags;
//或用构造函数
var regExp2 = new RegExp(pattern[, flags]);
pattern:正则表达式的匹配模式flags:可选,正则表达式的标识,也可选多个。g全局匹配,i忽略大小写,m匹配多行
一颗超简单的栗子:
var regExp = /abc/;
"abcdefg".replace(regExp, "WOW"); // "WOWdefg"
常用特殊字符
1.字符集合
| 字符 | 举例 | 含义 |
| [] | [xyz] | xyz中任意一个字符 等价于[x-z] |
| [^] | [^xyz] | 匹配任意不在xyz中的一个字符,等价于[^x-z] (注意与^x区分,后者表示匹配以x开头的字符) |
| [-] | [1-3] | 匹配123中的任意一个字符,等价于[123] |
2.字符类别
| 字符 | 含义 |
| . | 除\r和\n之外的任意字符,等价于[^\r\n] |
| \d | 数字0-9,等价于[0-9] |
| \D | 非数字字符,等价于[^0-9] |
| \w | 字母数字下划线,等价于[A-Za-z0-9_] |
| \W | 非字母数字下划线,等价于[^A-Za-z0-9_] |
| \s | 空白符 |
| \S | 非空白符 |
| \n | 换行符 |
3.需要转义的字符
正则模式中,需要用斜杠转义的:
* + ? $ ^ . | \ ( ) { } [ ]
需要特别注意的是,如果使用RegExp方法生成正则对象,转义需要使用两个斜杠,因为字符串内部会先转义一次。
4.边界
| 字符 | 举例 | 含义 |
| ^ | ^a | 以a开头(注意与[^]区分,后者表示匹配不在[^]中的元素) |
| $ | a$ | 以a结尾 |
| \b | \bsmart,smart\b | 单词边界,即[A-Za-z0-9_]之外的字符 |
| \B | \Bsmart | 非单词边界 |
举个栗子说 \b 和 \B :
"You are smart, but she is smarter.".replace(/smart\b/,"kind");
//"You are kind, but she is smarter."
"You are smart, but she is smarter.".replace(/smart\B/,"kind");
//"You are smart, but she is kinder."
if(看不懂){ 就置几动手试试吧 (ง •̀_•́)ง }
5.数量词
| 字符 | 含义 |
| ? | 匹配前面的模式 0或1次 |
| * | 匹配前面的模式 0或多次 |
| + | 匹配前面的模式 1或多次 |
| {n} | 匹配前面的模式 n次 |
| {n,} | 匹配前面的模式 至少n次 |
| {n,m} | 匹配前面的模式 至少n次,至多m次 |
| {0,m} | 匹配前面的模式 至多m次 |
6.贪婪与懒惰(非贪婪)
默认是贪婪模式匹配,即匹配尽可能多的字符。
var regExp1 = /\d{3,6}/;
"1234567890".replace(regExp1, "X");
//"X7890"
若想手动开启懒惰模式,需要在模式后加 ?
var regExp1 = /\d{3,6}?/;
"1234567890".replace(regExp1, "X");
//"X4567890"
7.分组与反向引用
分组又叫“子表达式”,把完整的正则表达式分成一个个小组,然后反过来用“组号”去引用这些小组就叫“反向引用”。
用例子来说:
//无分组
var regExp1 = /abc{2}/; //这样量词{2}只能匹配到c一个字符
//分组
var regExp2 = /(abc){2}/; //这样量词{2}就可以匹配到abc三个字符啦
//同时 abc 也有了一个组号 $1
再看一个栗子:
var reg = /(\d{1}).*(\d{2}).*(\d{3})/;
"1sss23sss456".replace(reg,"$1?$2?$3");
//"1?23?456"
上面的栗子换一种使用分组的方式:
var reg = /(\d{1}).*(\d{2}).*(\d{3})/;
var result = reg.exec("1sss23sss456");
console.log(result[1]+"-"+result[2]+"-"+result[3]);
//"1-23-456"
常用方法
正则对象的方法
1.RegExp.prototype.test()
测试当前正则是否能匹配目标字符串,返回布尔值。
var reg = /\d{2}/;
var str = "1sss23sss456";
reg.test(str); //true
2.RegExp.prototype.exec()
在目标字符串中执行一次正则匹配操作,返回匹配的子字符串。
var reg = /\d{2}/;
var str = "1sss23sss456";
var result = reg.exec(str);
result[0]; //23
result.index; //4
result.input; //"1sss23sss456"
3.RegExp.prototype.toString()
返回一个字符串,其值为该正则对象的字面量形式。覆盖了Object.prototype.toString() 方法。
var reg = /\d{2}/;
reg.toString(); // "/\d{2}/"
字符串对象的方法
1.replace()
返回替换后的值
var reg = /\d{2}/;
var str = "1sss23sss456";
str.replace(reg,"?"); //"1sss?sss456"
2.match()
与exec()类似,返回匹配的子字符串。
var reg = /\d{2}/;
var str = "1sss23sss456";
str.match(reg); //["23"]
与exec()的区别在于:当正则表达式加了g标识符时,结果不同。看栗子:
var reg = /\d{2}/g;
var str = "1sss23sss456";
reg.exec(str); //["23"]
str.match(reg); //["23","45"]
3.search()
返回匹配的首字符的位置。
var reg = /\d{2}/;
var str = "1sss23sss456";
str.search(reg); //4
4.split()
返回分割后的数组。
var reg = /\d{2}/;
var str = "1sss23sss456";
str.split(reg); //["1sss","sss","6"]
小练习
写一个匹配手机号的正则(第一位是1,第二位是[3,4,5,7,8]中的一个,后面还有9位数字)
写一个匹配 2017-01-01 或 2017/01/01 这两种格式日期的正则表达式
————答案:
/^134578{9}$/
/^d{4}[-/]d{2}[-/]d{2}$/
应用
1.使用正则改变数据结构
var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
console.log(newstr); //Smith, John
2.在多行中使用正则表达式
var s = "Please yes\nmake my day!";
s.match(/yes.*day/); // null
s.match(/yes[^]*day/); //'yes\nmake my day'
3.从URL中提取子域名
var url = "http://xxx.domain.com";
console.log(/[^.]+/.exec(url)[0]); // "http://xxx"
console.log(/[^.]+/.exec(url)[0].substr(7)); // "xxx"
匹配除了.之外的任意元素,一到多个字符。
“不会应用等于没有学会”,热烈欢迎小伙伴们在评论区补充你平时用到正则表达式的地方,然后我会添加在文章里,我们一起来收集吧 ヽ(•̀ω•́ )ゝ
参考: