JavaScript正则表达式
RegExp类型
- 构造函数形式创建
- 字面量形式创建
RegExp (pattern, flags) //构造函数
var reg1 = /\d{4}\w{2}/g //字面量形式
var reg2 = new RegExp(/\d{4}\w{2}/g)
//等价于
var reg2 = new RegExp("\\d{4}\\w{2}", "g")
var reg2 = new RegExp(/d{4}\\w{2}/gi, "g") //ES5会报错,ES6中忽略字面量后的标志g和i
注:pattern为模式,可以为字符串(字符串形式的模式需要进行双重转义)或正则表达式字面量。
正则表达式对象属性
- global:是否全文搜索,默认false
- ignoreCase:是否大小写敏感,默认false
- multiline:多行搜索,默认值false
- lastIndex:是当前表达式匹配的最后一个字符的下一个位置
- source:正则表达式的文本字符串
var reg = /a12/g
reg.test('a12abc')
reg.lastIndex //3
reg.global //true
reg.ignoreCase //false
reg.multiline //false
reg.source "a12"
匹配模式
- g,全局模式,应用于所有字符串,而非发现第一个匹配项后就停止
- i,表示不区分字母大小写
- m,多行匹配模式
- u,Unicode模式,可以正确的匹配4个字节UTF-16编码字符(E6支持)
- y,粘连模式,与g相似,但下一次匹配项需满足在上一匹配项紧贴之后的位置
//匹配开头为123的字符串
var reg1 = /^123/g
var reg2 = /^123/gm
//str为多行文本
var str =
"123ab
123ac
ac32"
reg1.exec(str) //仅能匹配到第一行的123,再次执行匹配为null
reg1.exec(str) //null
//多行匹配模式
reg2.exec(str) //匹配到123
reg2.exec(str) //可以匹配到第二行的123
reg2.exec(str) //null
//注意非全局模式下,永远只得到到第一个匹配项,所以上方的正则表达式如果去除g,执行exec函数可以一直得到123
元字符
注:匹配元字符本身需要转义,即使用元字符\
. 匹配除回车(\r)换行符(\n)以外的所有字符
\ 用于转义元字符
^ 表示字符串的开始,/^a/ 表示必须以a开头,一些场景下还有表否定的意思
$ 表示字符串结尾
| 表示或,(a|b)dc 可以匹配abc也可以匹配bdc
量词元字符
? 表示出现0或1次
+ 表示出现至少1次
* 表示出现任意次
{} 可以用于出现n次或出现范围的次数
a{3}表示a出现三次,a{3,6}表示出现3到6次;
匹配时默认进行贪婪匹配,如aaaa,a{3,6}会尽可能的匹配,即aaaa;
非贪婪匹配,a{3,6}? 加上?后仅匹配前3个a
分组元字符
() 可以将匹配字符串进行分组
$1,$2……,分别表示第1个分组,第2个分组……
var str = "2020-10-10"
var reg = /(\d{4})-(\d{2})-(\d{2})/g
str.replace(reg, "$2/$3/$1") //"10/10/2020"
RegExp.$1 //"2020"
在接受正则表达式的字符串方法中$1可直接访问第1分组,在一般环境中可以用RegExp.$1获取最近匹配项的第1个分组
范围元字符
[] 只要包含在里面的字符都能匹配成功
匹配数字 [0-9]
匹配字母 [a-zA-Z]
匹配数字字母和邮箱符号 [0-9a-zA-Z@]
预定义范围类
. 匹配除了回车换行外的所有字符,相当于[^\r\n]
\d 匹配数字字符,相当于[0-9]
\D 匹配非数字字符,相当于[^0-9]
\s 匹配空白符,相当于[\t\n\x0B\f\r]
\S 匹配非空白符,相当于[^\t\n\x0B\f\r]
\w 匹配单词字符(字母、数字下划线),相当于[a-zA-Z_0-9]
\W 匹配非单词字符,相当于[^a-zA-Z_0-9]
边界
^ 起始边界
$ 结尾边界
\b 单词边界
\B 非单词边界
var str = "This is tom"
var reg1 = /is/g //可以匹配到两个is
var reg2 = /\bis\b/g //仅匹配到单独的单词is
var reg3 = /\Bis\b/g //仅匹配到This的is
前瞻
作用:进行匹配内容先于条件的匹配,断言assert的内容不会被放入匹配项
先行断言 exp(?=assert)
先行否定断言 exp(?!assert)
var str = "1 equals 100%"
//匹配%前面的数字
var reg = /\d+(?=%)/g
reg.exec(str) //仅匹配到"100"
//匹配非%前面的数字
var reg1 = /\d+(?!%)/g
reg.exec(str) //仅匹配到"1"
后顾(ES6后的提案,大多浏览器未实现)
作用:进行条件先于内容的匹配
后行断言 (?<=assert)exp
后行否定断言 (?<!assert)exp
具名组匹配(ES6后支持)
在分组前面使用**(?<name>exp)**可以对分组进行命名,具名组匹配到分组后可以通过groups对象访问到具名组匹配的内容。
var reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
var str = "1999-04-23"
var arr=reg.exec(str)
//通过groups对象访问具名组
arr.groups //{day: "23", month: "04", year: "1999"}
arr.groups.day //23
引用
正则表达式内可以同过**\k<name>**使用具名组的匹配规则
var reg = /(?<str>123)-\k<str>/
reg.test('123-123') //true
reg.test('123-abc') //false
字符串对象方法
部分字符串对象方法支持使用正则表达式,它们既支持字符串为参数,也支持正则表达式对象
- search(reg),该方法用于检索字符串中的指定子字符串,方法返回第一个匹配结果的index,查不到则返回-1。
var str = 'my name is tom'
reg = /is/
str.search(reg) //8
注:该方法会无视g标志,不能进行全局搜索,每次都从字符串的开始进行搜索
- match(reg),该方法用于匹配字符串中的一个或多个指定子字符串,非全局模式下返回一个带匹配项信息的数组(包含匹配项,分组等信息),全局模式g下返回匹配项的数组,没有匹配项返回null。
var str = 'what is your name? my name is tom.'
var reg1 = /is/
var reg2 = /is/g
str.match(reg1) //["is", index: 5, input: "what is your name? my name is tom.", groups: undefined]
str.match(reg2) //["is", "is"]
- split(reg),该方法接受一个参数(分割符),用于分割字符串
- replace(reg, replaceStr ),该方法用于匹配并替换字符串内容,第二个参数可以为字符串,也可以是函数。
var reg = /\bis\b/
var str = "this is tom"
str.replace(reg,'_') //"this _ tom"
//函数形式的应用
var reg1 = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
'2020-10-10'.replace(reg1, (
matched, //匹配项
capture1, //第一个分组
capture2, //第二个分组
capture3, //第三个分组
position, //匹配开始的位置
str, //原字符串
groups //具名组对象
) => {
let {day, month, year} = groups //解构赋值
return day+"/"+month+"/"+year
})
//"10/10/2020"