JavaScript RegExp 对象
当您检索某个文本时,可以使用一种模式来描述要检索的内容。RegExp 就是这种模式。
简单的模式可以是一个单独的字符。
更复杂的模式包括了更多的字符,并可用于解析、格式检查、替换等等。
您可以规定字符串中的检索位置,以及要检索的字符类型,等等。
1.基本用法
- 创建方式一:字面量方式定义
<script>
// 创建正则
var reg = /hello/
// 检测某个字符串是否有符合正则格式的文本
var flag = reg.test("hello world")
console.log(flag) // true
</script>
- 创建方式二:使用构造函数构建(如果存在转义字符,则在字符转义规则前加 \ ,第二个参数为修饰符)
<script>
// 创建正则
var reg = new RegExp("hello")
// 检测某个字符串是否有符合正则格式的文本
var flag = reg.test("hello world")
console.log(flag) // true
</script>
2.修饰符
- 修饰符用于执行区分大小写和全局匹配
修饰符 | 说明 |
---|---|
i | 查找字符串时,不区分大小写 |
g | 查找字符串时,进行全局匹配 |
m | 多行模式,遇到换行符则视为新的一行,则每行都可以匹配^和$ |
PS:在查找或者替换某段字符串时,如果传入的参数是字符串,则默认是全局匹配。而传入的是正则表达式的话,需要指定修饰符g才能开启全局匹配
- 区分大小写
<script>
// 默认会区分大小写
var reg = /hello/
var flag = reg.test("Hello World")
console.log(flag) // false
// 添加i修饰符 不区分大小写
var reg2 = /hello/i
var flag2 = reg2.test("Hello World")
console.log(flag2) // true
</script>
- 全局匹配:对于字符串调用的方法,这个标识表示一次性输出所有结果,而对于reg实例的方法,他表示会依次记录并更新要查询的起始下标
<script>
var str = "I'm in a bad mood, really bad"
// 默认非全局匹配
var reg3 = /bad/
var newStr = str.replace(reg3,"good")
// 只替换了一个bad
console.log(newStr) // I'm in a good mood, really bad
// 全局匹配
var reg4 = /bad/g
var newStr2 = str.replace(reg4,"good")
// 替换了全局的bad为good
console.log(newStr2) // I'm in a good mood, really good
</script>
- 多行匹配:遇到换行符后,把字符串看成两行看待,每行Hello World和javascript都可以独立匹配开头和结尾
<script>
// 创建字符串
var str = "Hello World\njavascript"
// 非多行模式(匹配已World结尾)
var reg = /World$/
console.log(reg.test(str)) //false
// 多行模式(匹配以World结尾)
var reg2 = /World$/m
console.log(reg2.test(str)) //true
// 多行模式(匹配以javascript开头)
var reg3 = /^javascript/m
console.log(reg3.test(str)) //true
</script>
3.字符
- 转义字符
( 转义为 \(
) 转义为 \)
{ 转义为 \{
} 转义为 \}
+ 转义为 \+
* 转义为 \*
? 转义为 \?
| 转义为 \|
. 转义为 \.
^ 转义为 \^
$ 转义为 \$
\\ 转义为 \\\\
- 元字符是拥有特殊含义的字符:
元字符 | 说明 |
---|---|
. | 查找单个字符,除了换行和行结束符。(通俗的说是任意字符) |
\d | 匹配数字0-9 |
\D | 匹配非数字 |
\s | 匹配空格(包括换行符、制表符、空格符等),相等于[ \t\r\n\v\f] |
\S | 匹配非空白字符 |
\w | 元字符用于查找单词字符。(单词字符包括:a-z、A-Z、0-9,以及下划线) |
\W | 元字符用于查找非单词字符 |
\b | 匹配词的边界,通俗的说,一个词的前面或者后面不可用有其他字符(结束符,分隔符除外) |
\B | 匹配非词边界,与上相反 |
4.范围匹配
- 方括号用于匹配某个范围内的字符,内部可用 "," 匹配多种字符
示例 | 说明 |
---|---|
[abc] | 匹配中括号中存在的一个字符(a,b,c中的一个) |
[^abc] | 匹配中括号中不存在的一个字符(除a,b,c中以外的字符) |
[^] | 匹配一切字符,其中包括换行符 |
[0-5] | 查找任何从 0 至 5 的数字 |
[a-h] | 查找任何从小写 a 到小写 h 的字符 |
[A-H] | 查找任何从大写 A 到大写 H 的字符 |
[A-Za-z] | 查找匹配所有26个字母,包括大小写 |
[A-Z,a-z] | 查找匹配所有26个字母,包括大小写,还有"," |
5.数量匹配
- 匹配0个或1个字符
var reg = /\d+/
var reg2 = /\d{0,1}/
- 匹配0个或多字符
var reg = /\d*/
var reg2 = /\d{0,}/
- 匹配至少1个字符
var reg = /\d+/
var reg2 = /\d{1,}/
- 匹配2个字符
var reg = /\d{2}/
- 匹配2-4个字符(贪婪,尽可能匹配长的)
var reg = /\d{2,4}/
- 匹配2个以上字符(贪婪,尽可能匹配长的)
var reg = /\d{2,}/
'12345678'.match(reg) //["12345678"]
- 匹配2个以上字符(禁止贪婪,尽可能匹配短的)
var reg = /\d{2,}?/g
'12345678'.match(reg) //['12', '34', '56', '78']
6.边界匹配
示例 | 说明 |
---|---|
^n | 匹配任何开头为 n 的字符串 |
n$ | 匹配任何结尾为 n 的字符串 |
7.实例属性和方法
- lastIndex:reg实例有一个属性lastIndex,记录最后一次调用当前实例方法对字符串检索时匹配到的下标位置(默认0,匹配不到则重置为0),如果带有修饰符g,则下次调用从此下标开始检索,从而忽略下标之前的字符串,如果不带修饰符g,lastIndex一律为0
- test():检测正则表达式是否能在指定字符串中查找到匹配的文本,返回true or false
<script>
var str = "hello world"
//全局匹配
var reg = /o/g
//默认下标
console.log(reg.lastIndex) //0
//连续调用三次(前2此可以匹配到)
console.log(reg.test(str)) //true
console.log(reg.lastIndex) //5
console.log(reg.test(str)) //true
console.log(reg.lastIndex) //8
//匹配失败,下标重置为0
console.log(reg.test(str)) //false
console.log(reg.lastIndex) //0
console.log('-----')
//非全局匹配
var reg2 = /o/
//连续调用2次(lastIndex一律为0)
console.log(reg2.test(str)) //true
console.log(reg2.lastIndex) //0
console.log(reg2.test(str)) //true
console.log(reg2.lastIndex) //0
</script>
- exec():用于检索字符串中的正则表达式的匹配,匹配失败返回 null,匹配成功以数组形式返回匹配的信息(调用一次返回一个匹配结果)
<script>
var str = "hello world"
//全局匹配
var reg = /o/g
//默认下标
console.log(reg.lastIndex) //0
//连续调用三次(一次只能匹配一个结果,即使带有修饰符g)
console.log(reg.exec(str)) //['o', index: 4, input: 'hello world', groups: undefined]
console.log(reg.lastIndex) //5
console.log(reg.exec(str)) //['o', index: 7, input: 'hello world', groups: undefined]
console.log(reg.lastIndex) //8
//匹配失败,下标重置为0
console.log(reg.exec(str)) //null
console.log(reg.lastIndex) //0
console.log('-----')
//非全局匹配
var reg2 = /o/
//连续调用2次
console.log(reg2.exec(str)) //['o', index: 4, input: 'hello world', groups: undefined]
console.log(reg2.lastIndex) //0
console.log(reg2.exec(str)) //['o', index: 4, input: 'hello world', groups: undefined]
console.log(reg2.lastIndex) //0
</script>
8.字符串方法
- match():查找字符串,将符合正则表达式规则的文本以数组形式返回,如果没有指定全局匹配,则只查找一次。找不到就返回null
<script>
var str = "hi66morning77"
// 匹配连续的2个数字 非全局匹配
var reg = /\d{2}/
console.log(str.match(reg)[0]) // 66
// 匹配连续的2个数字 全局匹配(推荐)
var reg2 = /\d{2}/g
console.log(str.match(reg2)) // ["66", "77"]
</script>
- search():返回目标自字符串第一次出现的索引值(所以全局匹配被忽略),作用与indexOf()一致,但是indexOf()只接收字符串作为参数
<script>
var str = "hi66morning77"
// 匹配连续的2个数字 非全局匹配
var reg = /\d{2}/
console.log(str.search(reg)) // 2
// 匹配a,b,m中的一个
var reg2 = /[abm]/
console.log(str.search(reg2)) // 4
</script>
- split():用于把一个字符串分割成字符串数组,参数可以是字符串,也可以是 正则表达式
<script>
var str = "When the night falls"
// 匹配连续的1个或多个空格
var reg = /\s+/
// 将字符串分割成为数组
var arr = str.split(reg)
console.log(arr) // ["When"," the","night","falls"]
</script>
- replace():查找字符并替换,第二个参数除了可以是静态的字符串,还可以是正则匹配到的内容($&),还可以是回调
<script>
var str = "When the night falls"
// 匹配连续的1个或1个以上的空格
var reg = /\s+/g
// 将多个空格替换成一个
var newStr = str.replace(reg," ")
console.log(newStr) // When the night falls
</script>
<script>
var str = "1 and 2"
//匹配数字
var reg = /\d+/g
//将字符串中的数字加倍
var str2 = str.replace(reg,function(match){
return match * 2
})
console.log(str2) //2 and 4
</script>
9.高级应用
- 或:使用 "|" 表示同时匹配多个条件,只要满足任意一个皆可,同时每个条件可以用()进行包裹,其内部可以单独控制字符和数量
<script>
//匹配中英文逗号和空格
var reg = /,|,|\s+/g
var str = "1,2,3 4 5"
//数组转换
var arr = str.split(reg)
console.log(arr) // ['1', '2', '3', '4', '5']
</script>
- 组匹配:通过"()"对组合多个匹配条件,除了能输出综合匹配结果,还能输出"()"内的匹配结果(正则表达式内部,还可以用\n引用括号匹配的内容,n是从1开始的自然数,表示对应顺序的括号)
<script>
//匹配标签名和标签内容
var html = "<p>hello world</p>"
//第一个 () 匹配标起始标签名,并将匹配结果同步到闭合标签,中间的 () 匹配标签内容
var reg = /<([a-z]+)>(.*)<\/(\1)>/
var match = html.match(reg)
//数组第一个元素输出综合匹配结果,后续数组元素输出 () 内匹配结果
//['<p>hello world</p>', 'p', 'hello world', 'p', index: 0, input: '<p>hello world</p>', groups: undefined]
console.log(match)
</script>
<script>
//网址匹配与解析
//网址
var website = "http://google.com/xxx"
//网址匹配(协议,固定分隔符,域名,路径)
var reg = /(http|https|ftp):\/\/([0-9A-z-_.]+)(\/[0-9A-z-_]*)/
//输出
var match = website.match(reg)
//['http://google.com/xxx', 'http', 'google.com', '/xxx', index: 0, input: 'http://google.com/xxx', groups: undefined]
console.log(match)
</script>
- 先行断言:指定匹配模式后面的字符必须被匹配,但又不返回这些字符,语法:匹配模式 (?= 匹配条件) 或者 匹配模式 (?! 匹配条件)
<script>
//待检
var str = "20%"
var str2 = "20"
//匹配百分比值,但是不输出%号
var reg = /\d+(?=%)/
var match = str.match(reg)
//['20', index: 0, input: '20%', groups: undefined]
console.log(match)
var match2 = str2.match(reg)
console.log(match2) //null
</script>
10.常用实例
匹配手机号(1开头,后面跟10个数字)
var reg = /^1\d{10}$/;
匹配QQ号(1-9开头,后面少则4个数字,多则10个数字。QQ号最少5位数,最多11位)
var reg = /^[1-9]\d{4,10}$/;
匹配身份证号(1-9开头,后面跟16个数字,最后面要么是X/x/数字)
var reg = /^[1-9]\d{16}[Xx\d]$/;
变量名检测(只能由字母,数字,下划线组成,且不能以数字开头,长度6-15)
var reg = /^[_,A-Z,a-z]\w{5,14}$/;
11.实际应用
- vue模版字符串解析
<script>
var data = {
name: "张三",age: 20
}
//仿vue字符串解析
var str = "{{name}} -- {{age}}"
//匹配Vue双括号语法
var reg = /\{\{(.*?)\}\}/g
//存储匹配结果
var match_list = []
while(true){
//执行匹配
var match = reg.exec(str)
//匹配失败则跳出循环
if(!match) break;
//缓存匹配结果
match_list.push(match)
}
//根据匹配结果对模版进行数据替换(从后到前)
for(var i=match_list.length-1;i>=0;i--){
//当前匹配项
var item = match_list[i]
//匹配的属性名
var key = item[1]
//属性名对应的值
var value = data[key]
//要替换的字符长度
var r_length = item[0].length
//替换下标
var index = item.index
//剪切
str = str.slice(0,index) + value + str.slice(index + r_length)
}
console.log('替换后的字符模版 = ',str) //张三 -- 20
</script>