JavaScript与正则表达式
阅读 (493)一、初识正则
1、正则介绍
-
什么是正则表达式?
要检索某个文本的时候,可以使用一种模式对这个文本的内容进行解析,这个模式可以是一个单独的字符,也可以是一系列复杂的字符,可以实现对文本内容的解析、校验、替换等功能。RegExp是正则表达式的缩写
-
为什么要用正则表达式?
前端往往有大量的表单数据校验的工作,采用正则表达式会使得数据校验的工作量大大减轻
假设用户需要在HTML表单中填写姓名、地址、出生日期等,那么在将表单提交到服务器进一步处理前,JavaScript程序会检查表单以确认用户确实输入了信息并且这些信息是符合要求的
2、创建正则表达式对象
构造函数法
-
格式
new RegExp(“模式”, “模式修饰词”)
-
参数说明
模式:匹配文本的规则
模式修饰词:可选参数,用来修饰模式用的,有"g" 、 “i"和"m”。"g"表示全局匹配,"i"表示忽略字母的大小写,"m"表示执行多行匹配,只影响
^
和$
,二者变成行的概念,即行开头和行结尾 -
示例
var pattern1 = new RegExp("good"); var pattern2 = new RegExp("good", "gi");
字面量法
-
示例
var pattern3 = /good/; var pattern4 = /good/gi;
3、RegExp对象的方法
test()
-
功能
查找字符串是否存在正则表达式所写的模式规则
-
返回值
布尔值,true表示找到符合,false表示没找到
-
注意
这个方法只要找到匹配模式中的规则,就立即返回true,就不会再往下找了,所以这个方法用“全局模式匹配”没用
-
示例
var str1 = "sunck is a good Good good man"; var parrent1 = new RegExp("nice"); var ret1 = parrent1.test(str1); console.log(ret1);
exec()
-
功能
查找字符串是否存在正则表达式所描述的模式规则
-
返回值
数组或者null,存在的话返回的是数组,数组中的第一个元素就是符合要求的字符串,不存在则返回null
-
示例
var str2 = "sunck is a good Good good man"; var parrent2 = new RegExp("good"); var ret2 = parrent2.exec(str2); console.log(ret2);
-
如果正则表达式的模式修饰符写成"g",exec()的工作原理
找到第一个匹配的字符串,并存储它所在的位置(下标),如果再次运行exec()检索同一个字符串的话,则从刚才存储的位置开始检索,并找到下一个匹配到的字符串,然后把该字符串的位置存储起来,以此类推。当检索到结果为null的时候,下一次在调用exec()方法时,会从头开始。如果正则表达式的模式修饰符没有用"g",则每次都是从头开始查找,返回的是第一次查找到的位置
var str3 = "sunck is a good Good good man"; var parrent3 = new RegExp("good", "gi"); var ret3_1 = parrent3.exec(str3); console.log(ret3_1); var ret3_2 = parrent3.exec(str3); console.log(ret3_2); var ret3_3 = parrent3.exec(str3); console.log(ret3_3); var ret3_4 = parrent3.exec(str3); console.log(ret3_4); var ret3_5 = parrent3.exec(str3); console.log(ret3_5);
注意:使用test()方法检索同一个字符串的话,也会对位置进行存储,所以当test()和exec()方法混合使用的时候要注意
compile()
-
功能
用于修改正则表达式模式的方法,也可以修改模式修饰符(可选)
-
示例
var str4 = "sunck is a good Good good nIce man"; var parrent4 = new RegExp("good"); parrent4.compile("nice", "i"); var ret4 = parrent4.exec(str4); console.log(ret4);
二、正则表达式的元字符
1、转义字符
符号:\
作用:将下一个字符转换成为一个特殊字符或一个原义字符
例如’n’匹配原义字符"n"。’\n’匹配特殊字符换行符
[]“匹配特殊字符[],而”[]“则匹配原义字符”[]"
‘’ 这个字符很特殊,在字符串也需要转义。用’\'表示
console.log("sunck \n sunck");
console.log("sunck \[\] sunck");
console.log("sunck \\ sunck");
2、匹配单个字符
匹配 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
[] | 里面是字符集合,匹配[]里任意一个字符 |
[0123456789] | 匹配任意一个数字字符 |
[0-9] | 匹配任意一个数字字符 |
[a-z] | 匹配任意一个小写英文字母字符 |
[A-Z] | 匹配任意一个大写英文字母字符 |
[A-Za-z] | 匹配任意一个英文字母字符 |
[A-Za-z0-9] | 匹配任意一个数字或英文字母字符 |
[^sunck] | []里的^称为脱字符,表示非,匹配不在[]内的任意一个字符 |
\d | 匹配任意一个数字字符,相当于[0-9] |
\D | 匹配任意一个非数字字符,相当于[^0-9] |
\w | 匹配字母、下划线、数字中的任意一个字符,相当于[0-9A-Za-z_] |
\W | 匹配非字母、下划线、数字中的任意一个字符,相当于[^0-9A-Za-z_] |
\s | 匹配空白符(空格、换页、换行、回车、制表),相当于[ \f\n\r\t] |
\S | 匹配非空白符(空格、换页、换行、回车、制表),相当于[^ \f\n\r\t] |
var str1 = "$sunck is a good manaABC";
//匹配 数字、字母中的任意一个和ABC
parrent1_1 = /[a-z0-9A-Z]ABC/;
console.log(parrent1_1.exec(str1));
//匹配 数字、空白符中的任意一个
parrent1_2 = /[\d\s]/;
console.log(parrent1_2.exec(str1));
3、锚字符
匹配 | 说明 |
---|---|
^ | 行首匹配,和[]里的^不是一个意思 |
$ | 行尾匹配 |
var str2 = "sunck is a good man!aABC";
//首字母不能是数字
parrent2_1 = /^\D/;
console.log(parrent2_1.test(str2));
//首字母必须是数字
parrent2_2 = /^\d/;
console.log(parrent2_2.test(str2));
//必须以字母结尾
parrent2_3 = /[a-zA-Z]$/;
console.log(parrent2_3.test(str2));
4、匹配边界字符
匹配 | 说明 |
---|---|
\b | 匹配一个单词的边界,指单词和空格的位置 |
\B | 匹配非单词边界 |
var str3 = "ack,nckab";
parrent3_1 = /ck\b/;
console.log(parrent3_1.exec(str3));
parrent3_2 = /ck\B/;
console.log(parrent3_2.exec(str3));
5、匹配多个字符
说明:以下使用x、y、z均为假设的普通字符,m、n表示一个数字,不是正则表达式的元字符
匹配 | 说明 |
---|---|
(xyz) | 匹配括号内的xyz,作为一个整体去匹配 |
x? | 匹配0个或者1个x,非贪婪匹配 |
x* | 匹配0个或任意多个x |
x+ | 匹配至少一个x |
x{n} | 确定匹配n个x,n是非负数 |
x{n,} | 至少匹配n个x |
x{n,m} | 匹配至少n个最多m个x |
x|y | |表示或的意思,匹配x或y |
var str4 = "sunck is a good gooddd good man!";
parrent4_1 = /good{2,4}/;
console.log(parrent4_1.exec(str4));
parrent4_2 = /sunck|kaige|kaishen/i;
console.log(parrent4_2.test(str4));
三、正则的高级使用
1、String类型中的正则表达式的应用
-
字符串.search(正则表达式对象)
功能:从"字符串"左侧开始查找"正则表达式对象"所匹配的子串
返回值:如果有匹配内容则返回第一个出现的下标,没有匹配则返回-1
注意:全局无用
var str1 = "sunck is a good Good good man"; console.log(str1.search(/good/i)); console.log(str1.search(/nice/i));
-
字符串.match(正则表达式对象)
功能:从"字符串"左侧开始查找"正则表达式对象"所匹配的子串
返回值:返回值是数组(这个是数组和我们传统常见的那个数组是一摸一样的) 或者 null
注意:如果使用后"g"的话可以匹配所有的子串
var str2 = "sunck is a good Good good man"; var ret2 = str2.match(/good/gi); console.log(ret2); console.log(ret2.length);
-
字符串.replace(被替换的字符串或正则表达式, 新的字符串)
功能:替换字符串
返回值:替换后的字符串
注意:使用"g"可以替换多个
var str3 = "sunck is a good Good good man"; var ret3 = str3.replace(/good/gi, "nice"); console.log(ret3);
-
字符串.split(要切割的字符串或正则表达式)
功能:切割字符串
返回值:切割后内容的数组
注意:使用"g"可以使用多个切割符
var str4 = "sunck is a good Good good man"; console.log(str4.split(/good/gi));
var str5 = "sunck#is&a*good@man"; console.log(str5.split(/[#&*@]/));
2、分组
只要正则中出现了小括号那么就会形成一份分组
-
捕获性分组
$1
,$2
…$9
是RegExp对象的静态属性。如果表达式模式中有括起来的子匹配,$1
…$9
表示第1个到第9个子匹配所捕获到的内容,如果有超过9个以上的子匹配,$1
…$9
属性分别对应最后的9个子匹配var reg=/([0-9]{3})([a-z]{2})/; var str="123ab"; console.log(str.match(reg));//{"123ab","123","ab"} console.log(RegExp.$1);//123 console.log(RegExp.$2);//ab
-
非捕获性分组(?:)
当我们加()只是为了提高优先级而不想捕获小分组时,可以在()中加?:来取消分组的捕获
var reg=/(?:[0-9]{3})([a-z]{2})/ var str="123ab" console.log(str.match(reg))//{"123ab","ab"}
-
分组的引用(重复子项)
只要在正则中出现了括号就会形成一个分组,我们可以通过\n (n是数字代表的是第几个分组)来引用这个分组,第一个小分组我们可以用\1来表示
需求:求出这个字符串’abAAbcBCCccdaACBDDabcccddddaab’中出现最多的字母,并求出出现多少次(忽略大小写)
var str = 'abbbbAAbcBCCccdaACBDDabcccddddaab'; str = str.toLowerCase().split('').sort(function(a,b){return a.localeCompare(b)}).join(''); var reg = /(\w)\1+/ig; var maxStr = ''; var maxLen = 0; str.replace(reg, function($0,$1){ console.log($0, $1); var regLen = $0.length; if(regLen>maxLen){ maxLen = regLen; maxStr = $1; }else if(maxLen == regLen){ maxStr += $1; } }); console.log(`出现最多的字母是${maxStr},共出现了${maxLen}次`);
3、正则的特性
-
贪婪性
所谓的贪婪性就是正则在捕获时,每一次会尽可能多的去捕获符合条件的内容。
如果我们想尽可能的少的去捕获符合条件的字符串的话,可以在量词元字符后加
?
-
懒惰性
懒惰性则是正则在成功捕获一次后不管后边的字符串有没有符合条件的都不再捕获。
如果想捕获目标中所有符合条件的字符串的话,我们可以用标识符
g
来标明是全局捕获
var str = '123aaa456';
// 只捕获一次,一次尽可能多的捕获
var reg = /\d+/;
var res = str.match(reg)
console.log(res)
//解决贪婪性、懒惰性
reg = /\d+?/g;
res = str.match(reg)
console.log(res)// ["1", "2", "3", "4", "5", "6"]
4、常用正则表达式
//1、检查邮政编码
//共6位数字
pattern = /^[\d]{6}$/;
console.log(pattern.test("223300"));
//2、检查文件压缩包
pattern = /^[\w]+\.zip$|rar$|gz$/;
console.log(pattern.test("sunck.zip"));
//3、删除多余空格
//g 必须全局,才能全部匹配
pattern = /\s/g;
var str1 = "sunck is a good man";
var str2 = str1.replace(pattern, "");
console.log("str2 = " + str2);
//4、删除开始和结尾的空格
var str3 = " sunck is a good man ";
pattern = /^\s+/;
var str4 = str3.replace(pattern, "");
console.log("str4 = " + str4 + "!");
pattern = /\s+$/;
var str5 = str4.replace(pattern, "");
console.log("str5 = " + str5 + "!");
//5、简单的电子邮件验证163邮箱
parrent = /^[a-zA-Z_]\w*@163.com$/
console.log(parrent.test("sunck@163.com"));