目录
正则表达式(Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。
正则表达式(Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。
一、什么是正则表达式
正则表达式是由一个字符序列形成的搜索模式。
当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容。
正则表达式可以是一个简单的字符,或一个更复杂的模式。
正则表达式可用于所有文本搜索和文本替换的操作。
二、正则表达式的创建
1.构造函数创建new RegExp('正则表达式','修饰符')
ignoreCase(忽略大小写)、global(全局匹配)、multiline(多行匹配)
2.直接字面量/正则表达式/修饰符
(1)exec
可用来匹配字符串中符合正则表达式的字符串
如果匹配到,返回值是一个result数组:
匹配的内容,index: 在str中匹配的起始位置,input: 参数字符串,groups: undefined]
否则返回null
(2)test
用来测试待检测的字符串中是否有可以匹配到正则表达式的字符串,
如果有返回true,否则返回false
// 1.构造函数创建new RegExp('正则表达式','修饰符')
// Hello和hello都能匹配到
var reg = new RegExp('hello', 'igm')
var str = 'Hello guangqi hello evan'
console.log(reg.exec(str))
console.log(reg.exec(str))
// console.log(res[0],res['index'],res.input)
console.log('--------------------------------------');
// // 关掉全局匹配 只能匹配到第一个大写的Hello
var reg = new RegExp('hello', 'im')
var str = 'Hello guangqi hello evan'
console.log(reg.exec(str))
console.log(reg.exec(str))
console.log('--------------------------------------');
// 2.直接字面量/正则表达式/修饰符
var reg1 = /evan/igm
var str1 = 'evan osborn Evan'
console.log(reg1.exec(str1));
console.log(reg1.exec(str1));
console.log('--------------------------------------');
// var str = 'Hello wrold javascript hello';
// var reg = new RegExp('hello','igm');
// var reg1 = /hello/igm;
/**
* 正则表达式实例方法 RegExprototype.exec
* 参数:要匹配字符串 返回值:数组或者null 匹配到返回一个数组
* [
'Hello',
index: 0,
input: 'Hello wrold javascript hello',
groups: undefined]
// * */
// console.log(reg.exec(str));
// console.log(reg.exec(str));
// console.log(res[0],res['index'],res.input)
// 想要全局匹配字符
var str2 = 'hello evan Hello Evan' //字符串
var reg2 = new RegExp('evan', 'igm') // 创建正则表达式
// var reg3 = /evan/igm
while(true){
var res = reg2.exec(str2) // 匹配字符串中符合正则表达式的字符串
// 如果不是符合正则表达式的字符串
if(!res){
// 跳出循环
break
}
// res[0]打印内容
console.log(res[0], res.index);
}
// while(true){
// var res = reg.exec(str);
// if(!res){
// break;
// }
// console.log(res[0],res.index)
// }
三、正则表达式实例方法
1.exec
可用来匹配字符串中符合正则表达式的字符串
如果匹配到,返回值是一个result数组:
[匹配的内容,index: 在str中匹配的起始位置,input: 参数字符串,groups: undefined]
否则返回null
注意点:
1)如果正则表达式中有修饰符"g",这时,在正则表达式的实例reg中会维护lastIndex属性,记录下一次开始的位置,当第二次执行exec的时候,从lastIndex开始检索。 2)如果正则表达式中没有修饰符"g",不会维护lastIndex属性,每次执行从开始位置检索
2.test
用来测试待检测的字符串中是否有可以匹配到正则表达式的字符串,如果有返回true,否则返回false
注意点:
1)如果正则表达式中有修饰符"g",这时,在reg中会维护lastIndex属性,记录下一次开始的位置,当第二次执行test的时候,从lastIndex开始检索。 2)如果正则表达式中没有修饰符"g",不会维护lastIndex属性,每次执行从开始位置检索
3.toString/toLocaleString
把正则表达式的内容转化成字面量形式字符串/有本地特色的字符串(JS中没效果)
4.valueOf
返回正则表达式本身
/**
* 校验字符串匹配到正则表达式 test
* 参数:要匹配正则表达式得字符串 返回值:true false
*/
var str = 'hello evan'
var reg = new RegExp('evan')
// var reg1 = /evan/
// console.log(reg.exec(str));
console.log(reg.test(str)); // true
// var reg = /hello/;
// var str = 'hello world';
// console.log(reg.test(str));
/**
* toString toLocaleString 转为本地特色字符串
* valueOf 返回正则表达式本身
*/
console.log(reg.toString(), typeof (reg.toString())); // /evan/ string
console.log(reg.toLocaleString(), typeof (reg.toLocaleString())); // /evan/ string
console.log(reg.valueOf(), typeof(reg.valueOf())); // /evan/(红) object
console.log(reg, typeof reg); // /evan/(红) object
// console.log(reg.toString(),typeof (reg.toString()));
// console.log(reg.toLocaleString(),typeof (reg.toLocaleString()));
// console.log(reg.valueOf(),typeof (reg.valueOf()));
// console.log(reg,typeof reg);
四、正则表达式实例属性
1.lastIndex
当没设置全局匹配时,该属性值始终为0
设置了全局匹配时,每执行一次exec/test来匹配,lastIndex就会移向匹配到的字符串的下一个位置,当指向的位置后没有可以再次匹配的字符串时,下一次执行exec返回null,test执行返回false,然后lastIndex归零,从字符串的开头重新匹配一轮
可以理解成,每次正则查找的起点就是lastIndex
var str = 'evan evan evan evan'
var reg = /evan/g
// var reg1 = new RegExp('evan',g)
console.log(reg.lastIndex); // 0
console.log(reg.exec(str)); // [ 'evan', index: 0, input: 'evan evan evan evan', groups: undefined ]
console.log(reg.lastIndex); // 4
console.log(reg.lastIndex); // 4
console.log(reg.exec(str)); // [ 'evan', index: 0, input: 'evan evan evan evan', groups: undefined ]
console.log(reg.lastIndex); // 9
console.log(reg.lastIndex); // 9
console.log(reg.exec(str)); // [ 'evan', index: 0, input: 'evan evan evan evan', groups: undefined ]
console.log(reg.lastIndex); // 14
console.log(reg.lastIndex); // 14
console.log(reg.exec(str)); // [ 'evan', index: 0, input: 'evan evan evan evan', groups: undefined ]
console.log(reg.lastIndex); // 19
console.log(reg.lastIndex); // 19
console.log(reg.exec(str)); // null
console.log(reg.lastIndex); // 0
// 没设置全局匹配
// console.log(reg.lastIndex); // 0
// console.log(reg.exec(str)); // [ 'evan', index: 0, input: 'evan evan evan evan', groups: undefined ]
// console.log(reg.lastIndex); // 0
// var reg = /hello/g;
// var str = 'hello hello hello';
// 没开启全局匹配的结果
// console.log(reg.lastIndex);//0
// console.log(reg.exec(str));//[]
// console.log(reg.lastIndex);//0
// console.log(reg.lastIndex);
// console.log(reg.exec(str));
// console.log(reg.lastIndex);
// console.log(reg.exec(str));
// console.log(reg.lastIndex);
// console.log(reg.exec(str));
// console.log(reg.lastIndex);
// console.log(reg.exec(str));
// console.log(reg.lastIndex);
// console.log(reg.exec(str));
// console.log(reg.lastIndex);
console.log('-----------------------------------------------------------');
2. ignoreCase、global、multiline
判断正则表达式中是否有忽略大小写、全局匹配、多行匹配三个模式修饰符
3.source
返回字面量形式的正则表达式(类似于toString)
/**
* 正则表达式实例属性
* ignoreCase global multilinem 返回值 就是true false
* 判断正则表达式中是否有忽略大小写、全局匹配、多行匹配三个模式修饰符
* source
* 返回**字面量形式**的正则表达式(**类似于toString**)
*/
var pat = /evan/igm
console.log(pat.ignoreCase); //true
console.log(pat.global); // true
console.log(pat.multiline); // true
console.log(pat.source, typeof (pat.source)); // evan string
// var pattern = /hello/igm;
// console.log(pattern.ignoreCase);
// console.log(pattern.global);
// console.log(pattern.multiline);
// console.log(pattern.source,typeof (pattern.source));
五、字符分类
1.普通字符
字母、数字、下划线、汉字、没有特殊含义的符号(,;!@等)
实际上不是特殊字符的字符都是普通字符
2.特殊字符
\:将特殊字符转义成普通字符
3.模式修饰符
i:ignoreCase,匹配时忽视大小写
m:multiline,多行匹配
g:global,全局匹配
字面量创建正则时,模式修饰符写在一对反斜线后
六、正则表达式语法-元字符
1.直接量字符
正则表达式中的所有字母和数字都是按照字面含义进行匹配的,Javascript正则表达式语法也支持非字母的字符匹配,这些字符需要通过反斜线\作为前缀进行转义。
字符 | 匹配 |
---|---|
字母和数字字符 | 自身 |
\o | Null字符 |
\t | 制表符 |
\n | 换行符 |
\v | 垂直制表符 |
\f | 换页符 |
\r | 回车符 |
var reg = /\n/;
console.log(reg.test('hello world')); // false
console.log('hello \n world');
2.字符集合
一个字符集合,也叫字符组。匹配集合中的任意一个字符。你可以使用连字符‘-’指定一个范围
[abc] 查找方括号之间的任何字符
[0-9] 查找任何从0至9的数字
[^xyz] 匹配除xyz之外的任何字符 一个反义或补充字符集,也叫反义字符组。也就是说,它匹配任意不在括号内的字符。
可以通过使用连字符 '-' 指定一个范围内的字符。
注意:^写在[]里面是反义字符组
var reg = /[abc]/;
var reg = /[0-9]/;
var reg = /[^xyz]/;
// var str = 'aaa hello world1';
var str = 'xyz';
console.log(reg.test(str)); //f
3.边界符
^ 匹配输入开始。表示匹配行首的文本(以谁开始)。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符后的开始处。
$ 匹配输入结尾。表示匹配行尾的文本(以谁结束)。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符的前的结尾处。
如果 ^和 $ 在一起,表示必须是精确匹配。
var reg = /abc/;
console.log(reg.test('abc'));//t
console.log(reg.test('aabc'));//t
console.log(reg.test('aabcd'));//t
console.log('------------------------------------------------');
var reg = /^abc/;
console.log(reg.test('abc'));//true
console.log(reg.test('aabcd'));//false
console.log(reg.test('abcd'));//true
console.log('------------------------------------------------');
var reg = /abc$/;
console.log(reg.test('abc'));//t
console.log(reg.test('aabc'));//t
console.log(reg.test('abcd'));//f
console.log('------------------------------------------------');
// 精准匹配
var reg = /^abc$/;
console.log(reg.test('abc'));//true
console.log(reg.test('abcabc'));//false
console.log(reg.test('aabc'));//flase
console.log(reg.test('abcd'));//false
4.字符集合与"^"和"$"一起使用
// 三选一 只有是a 或者是 b 或者是c 这三个字母才返回 true
var reg = /^[abc]$/
console.log(reg.test('a')); //true
console.log(reg.test('b')); //true
console.log(reg.test('c')); //true
console.log(reg.test('aa'));//false
console.log(reg.test('abc'));//false
console.log('---------------------------------------------------------');
// 26个英文字母(大写和小写都可以),数字任何一个返回 true
var reg = /^[0-9A-Za-z]$/
console.log(reg.test('1'));//true
console.log(reg.test('A'));//true
console.log(reg.test('a'));//true
console.log(reg.test('123'));//false
console.log(reg.test('abc'));//false
console.log(reg.test('1a2b3cA'));//false
console.log(reg.test('!'));//false
console.log('---------------------------------------------------------');
//取反 方括号内部加上 ^ 表示取反,只要包含方括号内的字符,都返回 false 。
var reg = /^[^0-9A-Za-z]$/
console.log(reg.test('1'));//false
console.log(reg.test('A'));//false
console.log(reg.test('a'));//false
console.log(reg.test('!'));//true
5.零宽和非零宽单词边界
\b 匹配一个零宽单词边界(zero-width word boundary),表示一个单词(而非字符)边界,也就是单词和空格之间的位置,或者字符(\w)与字符串开头或者结尾之间的位置。
\B 匹配一个零宽非单词边界(zero-width non-word boundary),与"\b"相反。
/**
* \b 零宽单词边界 单词和空格之间位置
* \B 单词边界和单词边界中间得位置 不匹配单词边界
*/
var str = 'hello Evan osborn'
var reg = /\bevan\b/
console.log(reg.exec(str)); //null
var reg1 = /\bEvan\b/
console.log(reg1.exec(str)); // [ 'Evan', index: 6, input: 'hello Evan osborn', groups: undefined ]
var reg2 = /\Bva\B/
console.log(reg2.exec(str)); // [ 'va', index: 7, input: 'hello Evan osborn', groups: undefined ]
var reg3 = /\BVa\B/
console.log(reg3.exec(str)); //null
6.字符类
将直接量字符单独放进方括号内就组成了字符类,一个字符类可以匹配它所包含的任意字符。例如:/[abc]/ 就和字母"a"、"b"、"c"中的任意一个都匹配。"^"符号用来定义否定字符类,例如:/[^abc]/ 匹配的是"a"、"b"、"c"之外的所有字符。字符类可以使用连字符来表示字符范围,例如:/[a-z]/,要匹配拉丁字母表中任何字母和数字,[a-zA-Z0-9]
字符类 | 含义 |
---|---|
. | 匹配除换行符\n和回车符之外的任何单个字符,等效于[^\n\r] |
\d | 匹配一个数字字符,等效于[0-9] |
\D | [^0-9] |
\w | 匹配包括下划线的任何单个字符,包括A~Z,a~z,0~9和下划线"_",等效于 [a-zA-Z0-9_] |
\W | [^a-zA-Z0-9_] |
\s | 匹配任何Unicode空白字符,包括空格、制表符、换页符等,等效于[\f\t\n\r] |
\S | [^\f\t\n\r] |
// | . | 匹配除换行符\n和回车符之外的任何单个字符,等效于**[^\n\r]**
var str = '\nhello\r evan an'
var str = '\n\r'
var reg = /./ //匹配除\n\r之外得任意字符
console.log(reg.test(str)); // false
console.log('-----------------------------------------------');
// var str = '\nhello\r world js';
// var str = '\n\r';
// var reg = /./;//匹配除\n\r之外得任意字符
// console.log(reg.test(str));
/**
* 字符类 \d 等同于[0-9] 匹配任意数字
* \D 等同于[^0-9] 不匹配数字
*/
var reg = /\d/ //字符类 \d 等同于[0-9] 匹配任意数字
console.log(reg.test('123')); // true
console.log(reg.test('0')); // true
console.log(reg.test('a')); //false
console.log('-----------------------------------------------');
var reg = /\D/ //\D 等同于[^0-9] 不匹配数字
console.log(reg.test('123')); //false
console.log(reg.test('0'));//false
console.log(reg.test('a'));//true
console.log('-----------------------------------------------');
/**
* \w 匹配[0-9A-Za-z_]
* \W 匹配[^0-9A-Za-z_]
*/
// \w 匹配[0-9A-Za-z_]
var reg = /\w/
console.log(reg.test('1'));//true
console.log(reg.test('a'));//true
console.log(reg.test('A'));//true
console.log(reg.test('9a'));//true
console.log(reg.test('8aA'));//true
console.log(reg.test('_'));//true
console.log(reg.test('!'));//false
console.log(reg.test(' '));//false
console.log('-----------------------------------------------');
// \W 匹配[^0-9A-Za-z_]
var reg = /\W/
console.log(reg.test('1'));//false
console.log(reg.test('a'));//false
console.log(reg.test('A'));//false
console.log(reg.test('1a'));//false
console.log(reg.test('1aA'));//false
console.log(reg.test('_'));//false
console.log(reg.test('!'));//true
console.log(reg.test(' '));//true
console.log('-----------------------------------------------');
// var reg = /\w/;
// console.log(reg.test('a'));//true
// console.log(reg.test('A'));//true
// console.log(reg.test('_'));//true
// console.log(reg.test('1'));//true
// console.log(reg.test('!'));//false
// console.log(reg.test(' '));//false
// var reg = /\W/;//[^0-9A-Za-z_]
// console.log(reg.test('0'));//false
// console.log(reg.test('a'));//false
// console.log(reg.test('A'));//false
// console.log(reg.test('_'));//fasle
// console.log(reg.test('@'));//true
// console.log(reg.test(' '));//true
/**
* \s 匹配任何unicode空白符 空格 制表符 换行符 [\f\n\t\r]
* \S 匹配除以上字符之外得任意字符 [^\f\n\t\r]
*/
// \s 匹配任何unicode空白符 空格 制表符 换行符 [\f\n\t\r]
var reg = /\s/
console.log(reg.test('\n')); //true
console.log(reg.test('\f'));//true
console.log(reg.test('\t'));//true
console.log(reg.test('\r'));//true
console.log(reg.test(' '));//true
console.log(reg.test('a'));//false
console.log(reg.test('!'));//false
console.log('-----------------------------------------------');
// \S 匹配除以上字符之外得任意字符 [^\f\n\t\r]
var reg = /\S/
console.log(reg.test('\n'));//false
console.log(reg.test('\f'));//false
console.log(reg.test('\t'));//false
console.log(reg.test('\r'));//false
console.log(reg.test(' '));//false
console.log(reg.test('a'));//true
console.log(reg.test('!'));//true
// var reg = /\s/;
// console.log(reg.test(' '));//true
// console.log(reg.test('\n'));//true
// console.log(reg.test('a'));//false
// console.log(reg.test('1'));//false
// var reg = /\S/;
// console.log(reg.test('1'));//true
// console.log(reg.test('a'));//true
// console.log(reg.test('!'));//true
// console.log(reg.test(' '));//false
// console.log(reg.test('\n'));//false
七、数量词
字符 | 含义 |
---|---|
* | >=0次 |
+ | ≥1 次 |
? | 0或1次 |
{n} | n 次 |
{n,} | ≥n 次 |
{n,m} | n到m 次 |
/**数量词
* 1.* 匹配字符>=0次
* 2.+ 匹配字符>=1次
* 3.? 匹配字符0次 1次
* 4.{n} 匹配字符 n次
* 5.{n,} 匹配字符>=n次
* 6.{n,m} 匹配字符n到m次 n=<字符<=m
*/
// 1.* 匹配字符>=0次
var reg = /^e*$/
console.log(reg.test('')); //true
console.log(reg.test('e'));//true
console.log(reg.test('ee'));//true
// var reg = /^a*$/;
// console.log(reg.test(""));//true
// console.log(reg.test("a"));//true
// console.log(reg.test("aa"));//true
console.log('----------------------------------------------');
// 2.+ 匹配字符>=1次
var reg = /^e+$/
console.log(reg.test(''));//false
console.log(reg.test('e'));//true
console.log(reg.test('eeeeeeeeeeeeeee'));//true
// var reg = /^a+$/;
// console.log(reg.test(''));//false
// console.log(reg.test('a'));//true
// console.log(reg.test('aaa'));//true
console.log('-------------------------------------------------');
// 3.? 匹配字符0次 1次
var reg = /^e?$/
console.log(reg.test(''));//true
console.log(reg.test('e'));//true
console.log(reg.test('eee'));//false
// var reg = /^a?$/; // 0次或者1次
// console.log(reg.test(''));//true
// console.log(reg.test('a'));//true
// console.log(reg.test('aa'));//false
// console.log(reg.test('aaa'));//false
console.log('-------------------------------------------------');
// 4.{n} 匹配字符 n次
var reg = /^e{4}$/
console.log(reg.test(''));//false
console.log(reg.test('e'));//false
console.log(reg.test('eeee'));//true
// var reg = /^a{3}$/;//匹配a字符3次
// console.log(reg.test('aaa'));
// console.log(reg.test('aaaa'));
// console.log(reg.test('aa'));
console.log('-------------------------------------------------');
// 5.{n,} 匹配字符>=n次
var reg = /^e{3,}$/
console.log(reg.test(''));//f
console.log(reg.test('ee'));//f
console.log(reg.test('eee'));//t
console.log(reg.test('eeeeeee'));//t
// var reg = /^a{3,}$/;//匹配a字符>=3次
// console.log(reg.test('aaa'));
// console.log(reg.test('aaaa'));
// console.log(reg.test('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'));
// console.log(reg.test('aa'));
console.log('-------------------------------------------------');
// 6.{n,m} 匹配字符n到m次 n=<字符<=m
var reg = /^e{3,6}$/
console.log(reg.test('e'));//f
console.log(reg.test('eee'));//t
console.log(reg.test('eeee'));//t
console.log(reg.test('eeeee'));//t
console.log(reg.test('eeeeee'));//t
// var reg = /^a{3,6}$/;//匹配a字符3-6次
// console.log(reg.test('aa'));
// console.log(reg.test('aaa'));
// console.log(reg.test('aaaa'));
// console.log(reg.test('aaaaa'));
// console.log(reg.test('aaaaaa'));
// console.log(reg.test('aaaaaaa'));
console.log('-------------------------------------------------');
/*
* 匹配qq号: 不能以数字0开始,只能由数字组成,长度为5-11位
*/
var reg = /^[1-9]\d{4,10}$/ // 4+1 10+1
console.log(reg.test('01234'));//f
console.log(reg.test('2365'));//f
console.log(reg.test('23651'));//t
console.log(reg.test('23651111111'));//t
console.log(reg.test('2365111111111'));//f
// var reg = /^[1-9]\d{4,10}$/;
// console.log(reg.test('1112'));
// console.log(reg.test('26810'));
// console.log(reg.test('26810222222'));
// console.log(reg.test('268102222222'));
console.log('-------------------------------------------------');
/**
* 1.匹配身份证号 18位
* 不能以数字0开头,只能由数字组成,最后一位可能是x,X,数字
*/
var reg = /^[1-9]\d{16}[xX\d]$/
console.log(reg.test('1436342023062888454'));//f
console.log(reg.test('043634202306288845'));//f
console.log(reg.test('14363420230628884a'));//f
console.log(reg.test('14363420230628884X'));///t
console.log(reg.test('14363420230628884x'));//t
console.log(reg.test('143634202306288845'));//t
// var reg = /^[1-9]\d{16}[xX\d]$/;
// console.log(reg.test('14232520230628111x'));
// console.log(reg.test('14232520230628111a'));
// console.log(reg.test('1423252023062811'));
// console.log(reg.test('14232520230628112'));
2.贪婪匹配和非贪婪匹配
(1)贪婪模式:尽可能多的匹配(首先取最多可匹配的数量为一组进行匹配),当匹配剩余的字符串,还会继续尝试新的匹配,直到匹配不到为止,为默认模式。
(2)非贪婪模式:尽可能少的匹配(每次取最少匹配的数量为一组进行匹配),直到匹配不到为止 使用方法:在量词后加上 ?
/**
* 贪婪模式 默认模式 尽可能多的匹配字符 剩下得字符符合数量词继续匹配
* 不符合直接返回null
*/
//不加全局匹配
var reg = /\d{3,6}/
var str = '12345678910'
console.log(reg.exec(str)); //[ '123456', index: 0, input: '12345678910', groups: undefined ]
console.log(reg.exec(str)); //[ '123456', index: 0, input: '12345678910', groups: undefined ]
console.log(reg.exec(str)); //[ '123456', index: 0, input: '12345678910', groups: undefined ]
console.log('--------------------------------------------------------------------------------');
// 加全局匹配
var reg = /\d{3,6}/g
var str = '12345678910'
console.log(reg.exec(str)); //[ '123456', index: 0, input: '12345678910', groups: undefined ]
console.log(reg.exec(str)); //[ '78910', index: 6, input: '12345678910', groups: undefined ]
console.log(reg.exec(str)); //null
console.log('--------------------------------------------------------------------------------');
var reg = /\d{3,6}/g
var str = '12345678'
console.log(reg.exec(str)); //[ '123456', index: 0, input: '12345678910', groups: undefined ]
console.log(reg.exec(str)); //null
console.log(reg.exec(str)); //[ '123456', index: 0, input: '12345678910', groups: undefined ]
// var reg = /\d{3,6}/g;
// var str = '12345678910';
// console.log(reg.exec(str));
// console.log(reg.exec(str));
// console.log(reg.exec(str));
console.log('--------------------------------------------------------------------------------');
/**
* 非贪婪模式 尽可能少的匹配 当剩余字符串符合数量词最少匹配次数继续匹配
* 不合符直接返回null
*/
// 不加全局匹配
var str = '12345678910'
var reg = /\d{3,6}?/
console.log(reg.exec(str));//[ '123', index: 0, input: '12345678910', groups: undefined ]
console.log(reg.exec(str));//[ '123', index: 0, input: '12345678910', groups: undefined ]
console.log(reg.exec(str));//[ '123', index: 0, input: '12345678910', groups: undefined ]
console.log('--------------------------------------------------------------------------------');
// 加全局匹配
var str = '12345678910'
var reg = /\d{3,6}?/g
console.log(reg.exec(str));//[ '123', index: 0, input: '12345678910', groups: undefined ]
console.log(reg.exec(str));//[ '456', index: 3, input: '12345678910', groups: undefined ]
console.log(reg.exec(str));//[ '789', index: 6, input: '12345678910', groups: undefined ]
console.log(reg.exec(str));//null
console.log('--------------------------------------------------------------------------------');
var str = '12345'
var reg = /\d{3,6}?/g
console.log(reg.exec(str));//[ '123', index: 0, input: '12345', groups: undefined ]
console.log(reg.exec(str));//null
console.log(reg.exec(str));//[ '123', index: 0, input: '12345', groups: undefined ]
// var reg = /\d{3,6}?/g;
// var str = '12345678';
// console.log(reg.exec(str));
// console.log(reg.exec(str));
// console.log(reg.exec(str));
八、选择,分组,引用
1、选择
字符"|"用于分隔供选择的字符,选择项的尝试匹配次序是从左到右,直到发现了匹配项,如果左边的选择项匹配,就忽略右边的匹配项,即使它可以产生更好的匹配。
/**
* 选择 | html|css|js 从左到右依次匹配字符串 匹配到左侧就直接返回左侧
* 开启全局匹配 继续校验就会向右匹配
* 字符"|"用于分隔供选择的字符,选择项的尝试匹配次序是从左到右,直到发现了匹配项,
* 如果左边的选择项匹配,就忽略右边的匹配项,即使它可以产生更好的匹配。
*/
var reg = /evan|osborn|free/g
var str = 'hellofreeevanosborn'
console.log(reg.exec(str));//[ 'free', index: 5, input: 'hellofreeevanosborn', groups: undefined ]
console.log(reg.exec(str));//[ 'evan', index: 9, input: 'hellofreeevanosborn', groups: undefined ]
// console.log(reg.exec(str));
//[
// 'osborn',
// index: 13,
// input: 'hellofreeevanosborn',
// groups: undefined
// ]
console.log('----------------------------------------------------------------------------------------');
var reg = /html|css|js/g;
var str = 'hellowroldcsshtml';
console.log(reg.exec(str));//[ 'css', index: 10, input: 'hellowroldcsshtml', groups: undefined ]
console.log(reg.exec(str));//[ 'html', index: 13, input: 'hellowroldcsshtml', groups: undefined ]
console.log('----------------------------------------------------------------------------------------');
2、分组
/**
* 分组 () briupbriupbriup
*/
var reg = /evanevanevan/
console.log(reg.test('evan'));//f
console.log(reg.test('evanevan'));//f
console.log(reg.test('evanevanevan'));//t
console.log(reg.test('evanevanevanevan'));//t
console.log('----------------------------------------------------------------------------------------');
var reg = /^evanevanevan$/
console.log(reg.test('evan'));//f
console.log(reg.test('evanevan'));//f
console.log(reg.test('evanevanevan'));//t
console.log(reg.test('evanevanevanevan'));//f
console.log('----------------------------------------------------------------------------------------');
var reg = /^briupbriupbriup$/;
console.log(reg.test('briup'));//f
console.log(reg.test('briupbriup'));//f
console.log(reg.test('briupbriupbriup'));//t
console.log(reg.test('briupbriupbriupbriup'));//f
console.log('----------------------------------------------------------------------------------------');
var reg = /^(evan){3}$/
console.log(reg.test('evan'));//f
console.log(reg.test('evanevan'));//f
console.log(reg.test('evanevanevan'));//t
console.log(reg.test('evanevanevanevan'));//f
console.log('----------------------------------------------------------------------------------------');
var reg = /^(briup){3}$/;
console.log(reg.test('briup'));//false
console.log(reg.test('briupbriup'));//false
console.log(reg.test('briupbriupbriup'));//true
console.log(reg.test('briupbriupbriupbriup'));//false
console.log('----------------------------------------------------------------------------------------');
3、候选
一个分组中,可以有多个候选表达式,用 | 分隔:
/**
* 候选 选择分组综合
*/
var reg = /I like (evan|osborn|free)/
console.log(reg.test('I like evan'));//t
console.log(reg.test('I like osborn'));//t
console.log(reg.test('I like free'));//t
console.log(reg.test('I like Evan'));//f
// var reg = /I Like (html|css|js)/;
// console.log(reg.test('I Like html'));
// console.log(reg.test('I Like css'));
// console.log(reg.test('I Like js'));
// console.log(reg.test('I Like table'));
4.捕获与引用
被正则表达式匹配(捕获)到的字符串会被暂存起来。其中,由分组捕获的串会从1开始编号,于是我们可以引用这些串:
/**
* 匹配到字符串(捕捉 缓存)起来 在引用之前需要校验字符串
*/
var reg = /(\d{4})-(\d{2})-(\d{2})/
var str = '2005-01-09'
reg.exec(str)
// console.log(reg.exec(str));
// 引用
console.log(RegExp.$1);//2005
console.log(RegExp.$2);//01
console.log(RegExp.$3);//09
console.log('---------------------------------');
var reg = /(\d{4})-(\d{2})-(\d{2})/;
var str = '2023-06-28';
reg.exec(str);
// console.log(reg.exec(str));
// 引用
console.log(RegExp.$1);//引用第一次捕捉到得结果 2023
console.log(RegExp.$2);//引用第二次捕捉到得结果 06
console.log(RegExp.$3);//引用第三次捕捉到得结果 28
console.log('---------------------------------');
//嵌套分组的捕获
// 如果碰到类似/((apple) is (a (fruit)))/的嵌套分组,捕获的顺序是什么
var reg = /((Evan is) (a (cat)))/
reg.exec('Evan is a cat')
console.log(RegExp.$1);//Evan is a cat
console.log(RegExp.$2);//Evan is
console.log(RegExp.$3);//a cat
console.log(RegExp.$4);//cat
console.log('---------------------------------');
var reg = /((apple) is (a (fruit)))/
reg.exec('apple is a fruit')
console.log(RegExp.$1);//apple is a fruit
console.log(RegExp.$2);//apple
console.log(RegExp.$3);//a fruit
console.log(RegExp.$4);//fruit
console.log('---------------------------------');
/**
* 反向引用
* \1引用了第一个被分组所捕获的串,换言之,表达式是动态决定的。
* 注意,如果编号越界了,则会被当成普通的表达式:
*/
var reg = /(\w{3}) is \1/
console.log(reg.test('111 is 456'));//f
console.log(reg.test('111 is 111'));//t
console.log(reg.test('456 is 456'));//t
console.log('---------------------------------');
var reg = /(\w{3}) is \1/;
console.log(reg.test('kid is kid'));//t
console.log(reg.test('one is one'));//t
console.log(reg.test('kid is one'));//f
console.log(reg.test('one is kid'));//f
console.log(reg.test('123 is 123'));//t
console.log(reg.test('123 is 456'));//f
console.log('---------------------------------');
// 注意,如果编号越界了,则会被当成普通的表达式:
var reg = /(\w{3}) is \6/;
console.log(reg.test( 'kid is kid' )); // false
// console.log(reg.test( 'kid is \6' )); // true
九、String对正则表达式的支持
1、search
查找字符串中是否有匹配正则的字符串,有则返回字符串第一次出现时的位置,无则返回null
正则中无论是否有全局匹配都不会影响返回结果
/**
* search obj.sayName() arr.pop() fn.call()
* 查找字符串中是否有匹配正则的字符串,有则返回字符串第一次出现时的位置,无则返回null
* 正则中无论是否有全局匹配都不会影响返回结果
*/
var reg = /hello/g;
var reg1 = /hello/
var str = 'hello wrold hello';
console.log(str.search(reg));//0
console.log(str.search(reg1));//0
console.log('---------------------------------------------');
2、match
匹配字符串中符合正则表达式的字符串,并返回该字符串的一个数组,其中包括字符串内容、位置
如果正则设置全局匹配,则一次性返回所有符合正则表达式的字符串数组
如果其中添加了分组,返回符合要求的字符串以及分组的一个数组,但如果同时开启全局匹配则不会在数组中添加分组内容
/**
* match 字符串匹配符合正则表达式字符 匹配到返回第一次匹配到数组
* ['hello',index:0,input:"hello world hello",groups:undefiend]
* 如果开启全局匹配 会被所有符合正则得字符全部放到一个数组中
* [ 'hello', 'hello' ]
*/
var str = 'hello world hello';
var reg = /hello/;//['hello',index:0,input:"hello world hello",groups:undefiend]
var reg1 = /hello/g;//[ 'hello', 'hello' ]
console.log(str.match(reg));
console.log(str.match(reg1));
console.log('-----------------------------------------------');
var reg = /(he)llo/;//['hello','he',index,0,input]
var reg1 = /(he)llo/g;//[ 'hello', 'hello' ]
console.log(str.match(reg));
console.log(str.match(reg1));
console.log('--------------------------------------------');
3、split
/**
* split 以某种形式分割字符串将其转换为数组
*/
var str = 'terry123larry456tony';
// 以某种形式分割字符串将其转换为数组
var reg = /\d{3}/;//切割条件
console.log(str.split(reg));//[ 'terry', 'larry', 'tony' ]
console.log('--------------------------------------------');
4、replace
/**
* replace 满足正则表达式得内容会被替换 不会更改正则和字符串
*/
var str = 'wo shi tutuxiaotaoqi'
var reg = /tutuxiaotaoqi/
var res = str.replace(reg,'Evan')
console.log(res,str,reg); //wo shi Evan wo shi tutuxiaotaoqi /tutuxiaotaoqi/
console.log('--------------------------------------------')
var str = 'javascript';
var reg = /javascript/;
var res = str.replace(reg,'java');
console.log(res,str,reg);//java javascript /javascript/
十、前瞻表达式
在正则表达式当中有个东西叫做前瞻,有的管它叫零宽断言:
表达式 | 名称 | 描述 |
---|---|---|
(?=exp) | 正向前瞻 | 匹配后面满足表达式exp的位置 |
(?!exp) | 负向前瞻 | 匹配后面不满足表达式exp的位置 |
// 在正则表达式当中有个东西叫做前瞻,有的管它叫零宽断言:
// | **表达式** | **名称** | **描述** |
// | :--------: | :------: | :---------------------------: |
// | (?=exp) | 正向前瞻 | 匹配后面满足表达式exp的位置 |
// | (?!exp) | 负向前瞻 | 匹配后面不满足表达式exp的位置 |
var str = 'Hello, Hi, I am Hilary.';
// 后面一定要匹配什么
var reg = /H(?=i)/g; //把i前面的H
var newStr = str.replace(reg, "T"); //替换成T
console.log(newStr);//Hello, Ti, I am Tilary.
console.log('----------------------------------------------');
var str = 'Hello, Hi, I am Hilary.';
var reg = /(?=i)/g //i前面
var newStr = str.replace(reg,'T') //加上T
console.log(newStr);//Hello, HTi, I am HTilary.
console.log('----------------------------------------------');
var str = 'Hello, Hi, I am Hilary.'
var reg = /H(?!i)/g //将不是i前面的H
var newStr = str.replace(reg,'T') //替换成T
console.log(newStr); //Tello, Hi, I am Hilary.
console.log('----------------------------------------------');
var str = 'Hello, Hi, I am Hilary.';
// 后面一定不要匹配什么
var reg = /(?!i)/g; // 不是i前面的
var newStr = str.replace(reg, "T"); //都替换成或加上T
console.log(newStr);//THTeTlTlToT,T THiT,T TIT TaTmT THiTlTaTrTyT.T
十一、小练习
1.验证是否为11位有效手机号码?
-
以1为开头
-
第二位为3,4,5,7,8中的任意一位
-
最后以0-9的9个整数结尾
2.密码验证
匹配密码,必须包含大写,小写和数字,和特殊字符(!,@,#,%,&),且大于6位
//1.验证是否为11位有效手机号码?
// - 以1为开头
// - 第二位为3,4,5,7,8中的任意一位
// - 最后以0-9的9个整数结尾
var reg = /^1[34578][0-9]{9}$/
var str = '13133412983'
console.log(reg.test(str));//true
var reg = /^1[34578]\d{9}$/;
var str = '93858285646';
console.log(reg.test(str));//f
//2.密码验证
// 匹配密码,必须包含大写,小写和数字,和特殊字符(!,@,#,%,&),且大于6位
/**
* 分析: [A-Z] [a-z] \d [!@#%&]{6,}
* 出现顺序:不确定 (?=.*[A-Z]); 表示前面有可能有内容 也有可能没有内容
* ^[A-Za-z\d!@#%&]
* | . | 匹配除换行符\n和回车符之外的任何单个字符,等效于**[^\n\r]**
* * 匹配字符>=0次
* (?=exp) | 正向前瞻 | 匹配后面满足表达式exp的位置
*/
var reg = /(?=.*[a-z])(?=.*A-Z)(?=.*\d)(?=.*[!@#%&])^[A-Za-z\d!@#%&]{6,}$/
var str = '45erAftrwg@'
console.log(reg.test(str));
var reg = /(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[!@#%&])^[A-Za-z\d!@#%&]{6,}$/;
var str = '1!1A3a';
console.log(reg.test(str));