IMOOC
IMOOC copied to clipboard
JavaScript正则表达式
一、前言
该博文源自慕课网的《JavaScript正则表达式》课程。老师讲的生动有趣,由浅入深,是一门好课程。为了让自己更好记忆和继续深究正则表达式,因此写下该篇博文。下面推荐两个实用的在线网站: 正则表达式工具 代码及时响应在线网站
二、实例化正则对象
在JavaScript中,一共有两种方法实例化正则对象,下面请看具体的方法。
1、 字面量:var reg = /\bis\b/g;
【注意】
\b代表单词边界,g代表全文进行匹配。如果没有\b和g,会怎么样呢?请动手分别进行测试一下,下面给出测试模板,内容可自行更改。
测试:'he is a boy,This is a dog'.replace(reg,'IS');
2、 构造函数:var reg = new RegExp('\\bis\\b','g');
【注意】
在构造函数中,我们需要\来进行转义。
测试:'he is a boy,This is a dog'.replace(reg,'IS');
三、修饰符
在JavaScript正则表达式中,一共有三种修饰符,分别是一下三种。
1、 g:global 全文搜索,假如不添加的话,那么搜索到第一个匹配即停止;
测试:'He is a boy,she is here?'.replace(/\bis\b/g,'0');
2、 i:ignore case 忽略大小写,默认大小写敏感;
测试:'He is a boy,she IS here?'.replace(/\bis\b/gi,'0');
3、 m:multiple lines 多行搜索。
测试:'@123\n@234\n@345'.replace(/^@\d/gm,'Q');
四、元字符
JavaScript正则表达式中,元字符非常之多,下面我们一起来耐心看看。
1、 \s:匹配单个空格,等同于[\f\n\r\t\v];而\S则恰恰相反,它匹配的是非空格字符。
测试:/\s.+/.exec('This is a test String.');
【分析】
其中.含义是除了回车符和换行符之外的所有字符,+含义是出现一次或多次(至少出现一次),exec() 方法用于检索字符串中的正则表达式的匹配。假如有点晕,再来看看下面的栗子
var regs = /\s.+/
var str = "this is dog stil here"
// thishaha
console.log(str.replace(regs,"haha"))
【应用场景】 匹配任意空或空白字符,如果你什么也没输入,或输入的只有空格、回车、换行等字符,则匹配成功。这样就可以验证用户是否正确输入内容了。 【用法】
var reg=/^\s*$/;
if(reg.test(value)){
alert('请输入有效值');
return false;
}
【分析】 其中^含义是以什么为开始,*含义是出现零次或多次(任意次),$含义是以什么为结束,test() 方法用于检测一个字符串是否匹配某个模式.
2、 \w:表示单词字符,等同于字符集合[a-zA-Z0-9_];而\W表示非单词字符,等效于[^a-zA-Z0-9_]。
var reg = /\w+/;
var str='fengxiong';
alert(reg.exec(str));
【分析】 返回完整的fengxiong字符串,因为所有字符都是单词字符。
var reg = /\w+/;
var str='.className';
alert(reg.exec(str));
【分析】 结果显示匹配了字符串中的className,只有第一个“.”唯一的非单词字符没有匹配。
var reg = /\w+/;
var str='正则教程';
alert(reg.exec(str));
【分析】 试图用单词字符去匹配中文自然行不通了,返回 null。
var reg = /\W+/;
var str='正则教程';
alert(reg.exec(str));
【分析】 返回完整的字符串,因为,中文算作是非单词字符。
3、其他元字符 \f:匹配换页符; \n:匹配换行符; \r:匹配回车符; \t:匹配制表符; \v:匹配垂直制表符; \d:匹配数字; \D:匹配非数字; \b:匹配单词边界; \B:匹配非单词边界
来个测试题:将符合一个ab+数字+任意字符的字符串代替为B。 答案:'ab32432dab2,'.replace(/ab\d./g,'B');
五、重要元字符
1、^: 可以用来创建反向类/负向类,也就是不属于某类的内容,比如: 'a1b2c3d4'.replace(/[^abc]/g,'X');
又有以什么为开头的含义,比如: '1 fafs'.replace(/^\d\s/g,'Q');
2、[ ] 可以用来构建一个简单的类,也就是几个字符归纳为集合,比如: 'a1b2c3d4'.replace(/[abc]/g,'X');
可以使用[a-z]来连接两个字符表示从a到z的任意字符,比如: 'a1b2d3x4z9'.replace(/[a-z]/g,'A');
在[]组成的类内部是可以连写的,比如: 'a1b2d3x4z9B7A3N4M8'.replace(/[a-zA-Z]/g,'J');
如何在[]把-给算上呢?其实只要把-加在后面即可,比如: '2018-01-14'.replace(/[0-9-]/g,'A');
六、量词
?:出现零次或一次(最多出现一次); +:出现一次或多次(至少出现一次); *:出现零次或多次(任意次); {n}:出现n次; {n,m}:出现n到m次; {n,}:至少出现n次。
八、分组
1、使用()可以达到分组的功能,使用量词作用于分组,比如: 'a1b2c3d4'.replace(/([a-z]\d){3}/g,'X'); 'BoyGirl'.replace(/Boy|Girl/g,'X'); 'BoyGirlBoyBorl'.replace(/Boy(Gi|Bo)rl/g,'X');
2、分组的反向引用,比如,将2018-01-14 转换为 01/14/2018,对比下面两段代码的结果: '2018-01-14'.replace(/\d{4}-\d{2}-\d{2}/g,'$2/$3/$1'); '2018-01-14'.replace(/(\d{4})-(\d{2})-(\d{2})/g,'$2/$3/$1');
八、贪婪模式与非贪婪模式
1、贪婪模式:尽可能多的匹配,比如: '12345678'.replace(/\d{3,6}/g,'X');
2、非贪婪模式:让正则表达式尽可能少的匹配,也就是说一旦成功匹配则不再继续尝试,比如: '12345678'.replace(/\d{3,6}?/g,'X');
九、正则表达式训练营
1、用正则匹配手机号码
function tele(tel) {
if (tel.search(/^1[34578]\d{9}$/g) > -1) {
console.log("1");
} else {
console.log("0");
}
}
tele("13456799014");
【分析】 寻找以13、14、15、17或18开头,以9个数字结尾的字符,找到了就返回1,失败就返回0。search()方法去匹配字符串,如果匹配成功,就返回匹配成功的位置,如果匹配失败就返回-1
还有一种更加简便的方法:
function tele(tel) {
return /^1[34578]\d{9}$/g.test(tel);
}
console.log(tele("13456799014"));
【分析】 test()方法的返回值是布尔值,通过该值可以匹配字符串中是否存在于正则表达式相匹配的结果,如果有匹配内容,返回ture,如果没有匹配内容返回false。 【拓展】 match()方法去匹配字符串,如果匹配成功,就返回匹配成功的数组,如果匹配不成功,就返回null; replace()方法去匹配字符串,匹配成功的字符去替换新的字符串。
2、判断字符串是否包含了数字
function contain(str) {
var reg = /\d/g;
return reg.test(str);
}
console.log(contain("fds3af"));
3、给定字符串str,检查其是否包含连续重复的字母,包含返回true,否则返回false。
function contain(str) {
return /([a-zA-Z])\1/.test(str);
}
console.log(contain("fdsaaf"));
【分析】 "小括号包含的表达式所匹配到的字符串" 不仅是在匹配结束后才可以使用,在匹配过程中也可以使用。表达式后边的部分,可以引用前面 "括号内的子匹配已经匹配到的字符串"。引用方法是 "/" 加上一个数字。"/1" 引用第1对括号内匹配到的字符串,"/2" 引用第2对括号内匹配到的字符串……以此类推,如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号 "(" 在前,那这一对就先排序号。
4、判断是否以元音字母结尾。
function contain(str) {
return /[a,e,i,o,u]$/i.test(str);
}
console.log(contain("fdsaaa"));
5、给定字符串str,检车其是否包含3个连续的数字
function contain(str) {
return str.match(/\d{3}/g);
}
console.log(contain("1g556777"));
6、判断是否符合指定格式(正确格式示例:556-142-7489)
function contain(str) {
return /^(\d{3}-){2}\d{4}$/g.test(str);
}
console.log(contain("235-894-5623"));
【解析】 以3个数字加“-”开头,并且重复2次,最后为4个数字。
7、<OPTION value="待处理">待处理</OPTION> 写一个正则表达式,匹配 "<OPTION value="待处理">"
let str = '<OPTION value="待处理">待处理</OPTION>';
let regExp = /^<.*?>/g;
console.log(regExp.exec(str)[0]);
【分析】 以<开头,匹配除了回车符合换行符之外的所有字符,出现任意次,出现零次或一次,这就匹配到了所有的字符。exec()方法返回一个匹配项的数组,而match()方法返回所有匹配项组成的数组。
8、如何获取一个字符串中的数字字符,并按数组形式输出,如: dgfhfgh254bhku289fgdhdy675gfh输出[254,289,675]
let str = 'dgfhfgh254bhku289fgdhdy675gfh';
let regExp = /\d+/g;
console.log(str.match(regExp));
【分析】 +含义是出现一次或多次(至少出现一次)。
9、敏感词过滤
let str = '我草你妈哈哈背景天胡景涛哪肉涯剪短发欲望';
let regExp = /草|肉|欲|胡景涛/g;
let result = str.replace(regExp,"*");
console.log(result);
以上的是缩减版,下面来个完整版的:
let str = '我草你妈哈哈背景天胡景涛哪肉涯剪短发欲望';
let regExp = /草|肉|欲|胡景涛/g;
let result = str.replace(regExp, function (match) {
let len = match.length;
let str;
switch (len) {
case 1:
str = '*';
break;
case 2:
str = "**";
break;
case 3:
str = "***";
break;
default:
str = '****';
}
return str;
});
console.log(result); //我*你妈哈哈背景天***哪*涯剪短发*望
10、让2013-6-7 变成 2013.6.7
let str = '2013-6-7';
let regExp = /-/g;
console.log(str.replace(regExp, '.')); //2013-6-7
11、给定这样一个连字符串,写一个function转换为驼峰命名法形式的字符串 getElementById
var s1 = "get-element-by-id";
function camelCased(str) {
let regExp = /-(\w)/g;
str.replace(regExp, function(match, p) {
return p.toUpperCase();
})
}
camelCased(s1);
【分析】 \w代表的是单词字符
12、判断字符串中是否包含数字
let str1 = 'abc9efh';
let str2 = 'abcefg';
let regExp = /\d/;
console.log(regExp.test(str1)); // true
console.log(regExp.test(str2)); // false
13、判断连续重复字母
let str1 = 'abc3d4e5';
let str2 = 'aab2c3';
let regExp = /([a-zA-Z])\1/;
console.log(regExp.test(str1));//false
console.log(regExp.test(str2));//true
14、给定字符串 str,检查其是否包含 3 个连续的数字
- 如果包含,返回最新出现的 3 个数字的字符串
- 如果不包含,返回 false
let str1 = 'abc123efg';
function captureThreeNumbers(str) {
let res;
if (res = str.match(/\d{3}/)) {
return res[0];
} else {
return false;
}
}
console.log(captureThreeNumbers(str1)); //123
15、给定字符串 str,检查其是否符合美元书写格式
- 以 $ 开始
- 整数部分,从个位起,满 3 个数字用 , 分隔
- 如果为小数,则小数部分长度为 2
- 正确的格式如:$1,023,032.03 或者 $2.03,错误的格式如:$3,432,12.12 或者 $34,344.3
let regExp = /^\$\d{1,3}(,\d{3})*(\.\d{2})?$/;
console.log(regExp.test('$1.23')); //true
console.log(regExp.test('$111.23')); //true
console.log(regExp.test('$1111.23')); //false
console.log(regExp.test('$1,123.23')); //true
【分析】 以$开头,匹配数字符1到3个;匹配逗号(,)再匹配3个数字符,该规则出现零次或多次(即任意次);匹配句号(.),再匹配2个数字符,该规则出现零次或一次,并在结尾处。
16、对人口数字的格式化处理,三位数字用一个','(逗号)隔开
function numberWithCommas(x) {
//对右侧人口数字的格式化处理,三位数字用一个','(逗号)隔开
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
console.log(numberWithCommas(12345678))//12,345,678
【分析】 非单词边界,匹配右边有三个数字符的数(正向前瞻),匹配一次或者多次;匹配负向前瞻。
17、将单词is替换为IS
let str = 'English poetry is one of their great heritages';
console.log(str.replace(/\bis\b/,'IS'));
// English poetry IS one of their great heritages
18、实现数字转千分位
var reg = /\d{1,3}(?=(\d{3})+$)/g;
var str = "1234556789";
console.log(str.replace(reg,"$&,"));
【分析】 数字千分位的特点是:第一个逗号后面数字的个数是3的倍数,正则:/(\d{3})+$/;第一个逗号前最多可以有1至3个数字,正则:/\d{1,3}/。加起来就是/\d{1,3}(\d{3})+$/,?=含义是零宽度正预测先行断言,具体用法自行百度^_^ 【其他】
var reg = /\d{1,3}(?=(\d{3})+$)/g;
var str = 1234556789;
console.log(str.toString().replace(reg,"$&,"));
十、参考文章
由于正则表达式真的是难以灵活运用和讲清楚,因为它实在是太强大了,只有不断的训练自己,多看并多练才有可能完全掌握它,下面提供一些参考文章。