正则表达式定义
正则表达式(Regular Expression,简称为regex,regexp,或re)使用单个字符串来描述,匹配一系列符合某个句法规则的字符串搜索模式,属于对象范畴。可以理解为描述字符模式的对象
应用于文本搜索和文本替换的操作。
正则表达式语法
/正则表达式主体/修饰符(可选)
实例:
var reg1=/example/i
该语句定义并赋值了一个变量reg1 值为一个正则表达式。该正则表达式检索字符串example,后面的i为修饰符,指定不区分大小写。
正则表达式修饰符
i | 不区分大小写(找到第一个符合条件的字符串后就会停止检索) |
g | 执行全局匹配(不再只是找到第一个后停止检索,会在全局范围内进行查找) |
m | 执行多行匹配,这个模式下每一行具有一个字符串开头和字符串结尾 |
正则表达式相对于一般的字符串检索模式,增加了多种修饰符改变检索模式。使得文本处理工作在某些不严格区分大小写,检索全文某字符串等情况下更加便利。
eg:看不懂上文可以看代码实现效果,看得懂建议跳过代码段
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var str1="One\ntwo\nthree\nfour\nfive";
var reg1=/o/g;
console.log(str1.replace(reg1,"?"));
//全局匹配o,并且只限定小写,故第一处O没有替换 其余各处o被替换
var reg2=/o/i;
console.log(str1.replace(reg2,"?"));
//不区分大小写替换,但只是替换一个
reg2=/o/gi;
console.log(str1.replace(reg2,"?"));
//这里同时使用两个修饰符g和i,替换掉全部o和O
var reg3=/e$/g
console.log(str1.replace(reg3,"?"));
//这里匹配以e为结尾的字符,只是全局匹配,并非多行匹配,因此只有一个five以e结尾
reg3=/e$/gm;
console.log(str1.replace(reg3,"?"));
//这里匹配以e结尾的字符,执行多行匹配模式后,one和three和five中最后的e都会被替换
//在多行匹配模式下每一行都有独立的结尾可以被e$筛选到
</script>
</body>
</html>
如果多行匹配还有问题可以参考这里
正则表达式的创建
正如同其他对象的创建,正则表达式可以使用字面量直接创建,也可以使用构造函数创建。值得注意的是字面量创建时需要把要匹配的字符串放在两个斜杠内。
eg:var reg1=/a/ ------------------使用字面量创建
eg:var reg2=new RegExp("s","i"); ---- 使用构造函数创建
注意:使用构造函数创建时可以有两个参数,分别对应正则表达式主体和正则表达式修饰符
字面量创建正则表达式时需要注意的字符
正如换行这样的字符,需要特殊方式表达,否则在书写代码的过程中会当作代码的换行而不是匹配换行符。这些字符需要使用反斜线(\)来间接表示出来。
- \o----------NULL字符
- \t-----------制表符
- \n----------换行符
- \v----------垂直制表符
- \f-----------换页符
- \r-----------回车符
- \xnn-------十六进制指定的字符,后面的nn不确定,可以是十六进制数字
- \uxxxx-----十六进制指定的unicode字符,nnnn为确定的十六进制数字
- \cX---------控制字符^X。详情可以在这里找到。
字符类
字符 | 匹配 |
[abc] | 方括号内的任意字符,对a可以匹配,对b也可以匹配······ |
[^abc] | 非方括号内的任意字符,可以为d,e,f······,就是不能为a或b或c |
\w | 任何ascll字符组成的单词,包含a到z,A到Z,0到9 |
\W | 任何非ascll字符组成的单词 |
\s | 任何unicode空白符(包括空白符,制表符·······) |
\S | 任何非unicode空白符 |
\d | 任何ascll编码的数字 包括0-9 |
\D | 任何非ascll编码的数字,除0-9以外的字符 |
\b | 匹配单词边界-前一个和后一个字符不全为\w(看不懂可以参考这里) |
以下附上个人测试中的代码,以上内容如看不懂或有疑问建议直接测试
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>测试页面</title>
</head>
<body>
<script>
var str1="??? EXAMPLE ONE TWO THREE GO";
var reg1=/[xao]/i;
console.log(str1.replace(reg1,"tihuan"));//第一处x被替换--匹配到其中任意一个,这次是x
reg1=/[^xao]/i;
console.log(str1.replace(reg1,"tihuan"));//匹配的是非方括号内的任意字符,这里匹配的是?
reg1=/./i;
console.log(str1.replace(reg1,"tihuan"));//.匹配的是任意换行符或unicode行终止符以外的任意字符,这里匹配的是?
str1="\nabcdef";
console.log(str1.replace(reg1,"tihuan"));//改变字符串后,换行符不变,a被替换。这里匹配的是a
reg1=/\w/i;
str1="\uffffabcdef";
console.log(str1.replace(reg1,"tihuan"));//改变字符串后,第一个字符串为unicode的字符,且范围远远超出ascll的范围,这里替换的是a
str1="a\uffffabcdef";
reg1=/\W/i;
console.log(str1.replace(reg1,"tihuan"));//这里把unicode编码的字符替换,其他不变
reg1=/\s/i;
str1="\tabc ";
console.log(str1.replace(reg1,"tihuan"));//这里替换的是制表符
reg1=/\S/i;
str1=" a a a";
console.log(str1.replace(reg1,"tihuan"));//这里替换的是a
reg1=/\d/i;
str1="a b,c 1 2 3";
console.log(str1.replace(reg1,"tihuan"));//针对数字进行替换,这里替换的是1
reg1=/\D/;
str1="1,2,3a,c,a"
console.log(str1.replace(reg1,"tihuan"));//针对非数字部分进行替换,这里替换的是,
reg1=/\b/;
str1="name space word";
console.log(str1.replace(reg1,"??"));//针对单词边界进行替换,这里直接在开头部分替换
</script>
</body>
</html>
重复字符类
针对某一字符重复出现多次,可以使用/aaa/表示,但这样针对大量重复出现的字符串并不适用。可以使用重复字符的语法来简化正则表达式。
字符 | 含义 |
{m,n} | 匹配前一项至少m次,最多n次 |
{m,} | 匹配前一项至少m次,无上限 |
{m} | 匹配前一项m次 |
? | 匹配前一项0或1次。等价于{0,1} |
+ | 匹配前一项1次或更多次,等价于{1,} |
* | 匹配前一项0次或更多次,等价于{0,} |
eg
var reg1=/\d{2,3}/ //->这里匹配一个数字2或3次
var reg2=/\w{2,}/ //->这里匹配一个字符2次及以上
var reg3=/a{3}/ //->这里匹配a3次
var reg4=/\s+apple\s+/ //->这里匹配前后各有至少一个空格的单词apple
正则表达式的锚字符
锚字符,指定匹配发生位置。
字符 | 含义 |
^ | 匹配字符串的开头,多行检索模式匹配每一行的开头 |
$ | 匹配字符串的结尾,多行检索模式匹配每一行的结尾 |
\b | 匹配单词的边界,\w与\W之间的位置--区分于[\b],这个匹配的是backspace(退格符) |
\B | 匹配非单词边界的位置 |
(?=pattern) | 零宽正向先行断言 要求后续内容和pattern这个正则表达式一致 |
(?!pattern) | 零宽负向先行断言 要求后续内容和pattern这个正则表达式不一致 |
(?<=pattern) | 零宽正向后行断言 |
(?<!pattern) | 零宽负向后行断言 |
这里的pattern为正则表达式
零宽:在匹配中不占用字符。
正向:后续字符符合给定的正则表达式,负向则是不符合。
先行:要求内容是在字符串的前面,后行则是在字符串后面
断言:查找具有某一特性的位置(如^$就是针对开头结尾,断言指定符合某种条件的位置。)
举例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var str1="a word";
var reg1=/wo(?=rd)/; //零宽正向先行断言
console.log(str1.replace(reg1,"?"));
//输出结果是a ?rd 不包含rd 只有wo
reg1=/wo(?!na)/; //零宽负向先行断言
console.log(str1.replace(reg1,"?"));
//输出结果同上,这里指定wo后面不能是na 然后字符串中的rd就可以被替换
reg1=/wo(?!rd)/
console.log(str1.replace(reg1,"?"));
//这次输出结果与原字符串一致。原因是零宽负向先行断言要求与指定后续内容不一致时才会检索到
reg1=/(?<=wo)rd/ //零宽正向后行断言
console.log(str1.replace(reg1,"?"));
//这次输出结果是a wo? 要求是前面字符为wo
reg1=/(?<!wo)rd/ //零宽负向后行断言
console.log(str1.replace(reg1,"?"));
//输出结果为原字符串 这里要求前置不能是wo 不符合
reg1=/(?<!wa)rd/
console.log(str1.replace(reg1,"?"));
//这次输出结果是a wo? 要求是前面字符不能为wa
</script>
</body>
</html>
正则表达式中特殊字符的作用
字符 | 含义 |
| | 匹配该符号前或后的内容 |
[] | 用于查找范围内的字符eg[0-9]查找数字[a-z]查找小写字母······ 当写成[abc]时,会针对a或b或c匹配 |
注意:| 这个字符从左到右计算,当左侧字符已经匹配到,也不会继续进行右侧字符的匹配。注意这种情况下可能造成的错误。
以下为测试代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var str1="a word";
var reg1=/[owrd]/;
console.log(str1.replace(reg1,"?"));
//输出结果是a ?ord 由此可以看出:针对原字符串的每一个字符,分别匹配正则表达式[]中的每一项
//而不是先以正则表达式中的o匹配一遍字符串
</script>
</body>
</html>
正则表达式应用
实际使用正则表达式处理文本时常常应用到字符串String的方法
replace | 检索第一个参数对于的字符串,并使用第二个参数字符串替换第一个参数对应的字符串。返回值为替换后的字符串,对原字符串无影响。未检索到就会不进行替换处理。 |
search | 检索参数字符串,并返回检索结果的字符串起始位置的下标。未找到返回-1. |
match | 参数是一个正则表达式,返回一个由匹配结果组成的数组。一般设置正则表达式为全局匹配模式,可以返回由所有符合匹配模式的字符串组成的数组。 |
split | 第一个参数是字符串或正则表达式,指定从什么位置切分字符串。第二个参数指定返回数组的最大长度,设定后返回的数组长度不会超过这个值,可以省略不写。 |
如果已经熟悉这几个方法可以不看以下代码
var str1="??? EXAMPLE ONE TWO THREE GO";
var reg1=/example/i;
var result1=str1.search(reg1);
console.log(result1);
输出结果是4,就是正则表达式检索文本的开头的下标。
var str1="??? EXAMPLE ONE TWO THREE GO";
var reg1=/example/i;
str1=str1.replace(reg1,"nine");
console.log(str1);
输出结果是"??? nine ONE TWO THREE GO",把example替换为nine
var str1="one two three four five";
var reg1=/\S\w+\S/g;
console.log(str1.match(reg1));
//输出一个数组Array(5) [ "one", "two", "three", "four", "five" ]
str1="..k.d..a...e....w";
reg1=/[a-z|A-Z]/g
console.log(str1.split(reg1));
//以字母为切割点,把字符串切割为数组
//输出内容为Array(6) [ "..", ".", "..", "...", "....", "" ]
后续还会更新一篇正则表达式对象的文章
本文参考菜鸟教程,《javascript权威指南》(第六版David Flanagan著)