JS基础:正则表达式
简介
正则表达式 (regular expression) 描述了一种字符串匹配的模式,可以用来检查一个字符串是否含有某种子串、将匹配的子串做替换或者从某个字符串中取出符合某个条件的子串等。在 JS 中,RegExp 对象和 String 对象的一些方法,如:"search()"、"match()"、"replace()" 等都支持正则表达式。
正则表达式的创建方式
1、实例创建方式:
var reg = new RegExp(pattern, modifiers);
2、字面量创建方式:
var reg = /pattern/modifiers
pattern:正则表达式
modifiers:修饰符
修饰符主要包括:
i:忽略大小写
m:多行匹配,即在到达一行文本末尾时还会继续寻常下一行中是否与正则匹配的项
g:全局匹配,模式应用于所有字符串,而非在找到第一个匹配项时停止
3、实例创建方式和字面量创建方式的区别:
实例创建方式可以进行字符串拼接,而字面量创建方式不可以,例如:
var str = 'test'; var reg1 = new RegExp(str + '123'); var reg2 = /str/; console.log(reg1); //输出 /test123/ console.log(reg2); //输出 /str/
实例创建方式需要进行字符串转义,而字面量创建方式不需要,例如:
//下面两条语句是等价的 var reg1 = new RegExp('\\d'); var reg2 = /\d/;
这是因为在字符串中 '\' 是转义字符,需要转义 '\',即 '\\'。
语法
1、修饰符
i | 不区分大小写 |
m | 多行匹配 |
g | 全局匹配 |
2、元字符
. | 匹配除了换行符 '\n' 以外的任意一个字符 |
\w | 匹配数字、字母和下划线 |
\W | 匹配数字、字母和下划线之外的任意一个字符 |
\d | 匹配数字 |
\D | 匹配非数字 |
\s | 匹配空白字符 |
\S | 匹配非空白字符 |
\b | 匹配单词边界 |
\B | 匹配非单词边界 |
\0 | 匹配 'null' 字符 |
\n | 匹配换行符 |
\f | 匹配换页符 |
\r | 匹配回车符 |
\t | 匹配制表符 |
\v | 匹配垂直制表符 |
3、量词
+ | 匹配 1 到多个 |
* | 匹配 0 到多个 |
? | 匹配 0 个或 1 个 |
{n} | 匹配 n 个 |
{n,} | 匹配 n 到多个 |
{n,m} | 匹配 n 到 m 个 |
x$ | 匹配结尾为 x 的字符串 |
^x | 匹配开头为 x 的字符串 |
?=x | 零宽度正先行断言,仅当子表达式 x 在字符串位置的右侧匹配时才匹配 |
?!x | 零宽度负先行断言,仅当子表达式 x 不在字符串位置的右侧匹配时才匹配 |
?<=x | 零宽度正后发断言,仅当子表达式 x 在字符串位置的左侧匹配时才匹配 |
?<!x | 零宽度负后发断言,仅当子表达式 x 不在字符串位置的左侧匹配时才匹配 |
4、方括号与圆括号
方括号用于给定某个范围的字符集合
[abcd] | 匹配给定集合中的任何字符 |
[^abcd] | 匹配给定集合外的任何字符 |
[0-9] | 匹配从 0 到 9 的数字 |
[a-z] | 匹配从 a 到 z 的字母 |
圆括号和计算表达式一样,可以提高优先级,也可以用于分组,例如:/a?/ 匹配 0 个或 1 个 'a',/(abc)?/ 则匹配 0 个或 1个 'abc'
5、优先级
\ :转义符
?: 、() 、[] :圆括号和方括号等
+ 、* 、? 、{n} 、{n,} 、{n,m} :量词限定符等
$ 、^ 以及任何元字符和字符
| :或操作
RegExp 对象的 test() 方法
RegExpObject.test(string) :用于检测一个字符串是否匹配某个模式,如果字符串中有匹配的值返回 true ,否则返回 false,例如:
var str = 'Hello World'; var reg = /Hello/; console.log(reg.test(str)); //输出 true
RegExp 对象的 exec() 方法
RegExpObject.exec(string) :用于检测一个字符串是否匹配某个模式,如果字符串中有匹配的值返回一个结果数组,否则返回 null,例如:
var str = 'Hello World'; var reg = /Hello/; console.log(reg.exec(str)); //输出 ["Hello", index: 0, input: "Hello World"]
此结果数组的第 0 个元素是与正则表达式匹配的文本,第 1 个元素是与第 1 个分组匹配的文本,第 2 个元素是与第 2 个分组匹配的文本,以此类推。除了数组元素和 length 属性外 exec() 方法还返回两个属性:index 属性保存的是匹配文本的第一个字符的位置,input 属性则存放的是被检索的字符串,例如:
var str = 'Hello World'; var reg = /Hel(lo)/; console.log(reg.exec(str)); //输出 ["Hello", "lo", index: 0, input: "Hello World"]
如果正则表达式使用了全局匹配修饰符 'g',那么在使用了 exec() 方法后,RegExpObject 对象的 'lastIndex' 属性会设置为匹配文本的最后一个字符的下一个位置,exec() 方法会在 'lastIndex' 指定的位置开始检索字符串,这时你需要手动反复调用 exec() 方法来全局匹配所有符合的文本,直到 exec() 方法再也找不到符合的文本时,它将返回 null,并把 'lastIndex' 属性重置为 0 ,例如:
var str = 'Hello World'; var reg = /Hello/; console.log(reg.lastIndex); //输出 0
var str = 'Hello World'; var reg = /Hello/g; console.log(reg.lastIndex); //输出 5
String 对象的 search() 方法
String.search(regExpObject) :用于检索与正则表达式相匹配的子字符串,如果检索到返回匹配子字符串第一个字符的位置,否则返回 -1,例如:
var str = 'Hello World'; var reg = /hello/i; console.log(str.search(reg)); //输出 0
String 对象的 replace() 方法
String.replace(regExpObject,newvalue) :用于替换与正则表达式相匹配的子字符串,返回替换后的新字符串,例如:
var str = 'Hello World'; var reg = /hello/i; console.log(str.replace(reg,'newString')); //输出 newString World
String 对象的 match() 方法
String.match(regExpObject) :用于检测一个字符串是否匹配某个模式,如果字符串中有匹配的值返回一个结果数组,否则返回 null,例如:
var str = 'Hello World'; var reg = /Hello/; console.log(str.match(reg)); //输出 ["Hello", index: 0, input: "Hello World"]
RegExp 对象的 exec() 方法和 String 对象的 match() 方法的区别:
1、当正则表达式没有分组,且非全局匹配时:exec() 方法和 match() 方法执行结果相同,均返回上述结果数组
2、当正则表达式有分组,且非全局匹配时:exec() 方法和 match() 方法执行结果相同,均返回上述结果数组,此结果数组的第 0 个元素是与正则表达式匹配的文本,第 1 个元素是与第 1 个分组匹配的文本,第 2 个元素是与第 2 个分组匹配的文本,以此类推
3、当正则表达式没有分组,且全局匹配时:exec() 方法和 match() 方法执行结果不同,exec() 返回上述结果数组(同非全局匹配),但是设置了 RegExpObject 对象的 'lastIndex' 属性,此时可以根据 'lastIndex' 属性的值反复调用完成全局匹配;match() 方法则直接返回一个数组,包含所有匹配的元素
4、当正则表达式有分组,且全局匹配时:exec() 方法和 match() 方法执行结果不同,exec() 返回上述结果数组(同非全局匹配);match() 方法则忽略分组,只保留全局匹配的元素
也就是说,在非全局匹配时,exec() 方法和 match() 方法是完全相同的,在全局匹配时,match() 方法会忽略分组,只保留全局匹配的元素,exec() 方法则不会忽略分组,而是通过 'lastIndex' 属性进行全局匹配