描述字符
描述字符分为普通字符和元字符。用于描述正则匹配规则的内容。普通字符即是数字字母和常用符号,用以描述自身。
元字符具有代表一类字符的特殊字符。
普通字符
var str = 'ac10_'
var r = /ac/g
console.log(str.match(r)) //["ac"]
//在r表示的正则表达式中ac为特殊字符,只能匹配str字符串中的ac字符。
元字符
// . :查找单个字符,除了换行和行结束符
var str = 'aZ1_?#\n\r'
var r = /./g
console.log(str.match(r)) //["a", "Z", "1", "_", "?", "#"]
// \w : 查找单词字符:a-z,A-Z,0-9,和_(下划线)字符
var str = 'aZ1_?#'
var r = /\w/g //g为全局匹配
console.log(str.match(r)) //["a", "Z", "1", "_"]
// \W : 查找非单词字符
var str = 'aZ1_?#'
var r = /\W/g
console.log(str.match(r)) //["?", "#"]
// \d : 查找数字
var str = 'aZ1_?#\n\r'
var r = /\d/g
console.log(str.match(r)) //["1"]
// \D : 查找非数字
var str = 'aZ1_?#\n\r'
var r = /\D/g
console.log(str.match(r)) // ["a", "Z", "_", "?", "#", "↵", ""]
// \n 查找换行符
var str = 'aZ1_?#\n\r \f\t \v'
var r = /\n/g
console.log(str.match(r)) //["↵"]
// \f 查找换页符
var str = 'aZ1_?#\n\r \f\t \v'
var r = /\f/g
console.log(str.match(r)) //[""]
// \r 查找回车符
var str = 'aZ1_?#\n\r \f\t \v'
var r = /\r/g
console.log(str.match(r)) //[""]
// \t 查找制表
var str = 'aZ1_?#\n\r \f\t \v'
var r = /\t/g
console.log(str.match(r)) //[" "]
// \v 查找垂直制表符
var str = 'aZ1_?#\n\r \f\t \v'
var r = /\v/g
console.log(str.match(r)) //[""]
// \s 查找空白字符。
//注: \n换行符、\f换页符、\r回车符 、\t制表符、\v 垂直制表符 都属于空白字符
var str = 'aZ1_?#\n\r \f\t \v'
var r = /\s/g
console.log(str.match(r)) //["↵", "", " ", "", " ", " ", ""]
描述字符范围
在正则表达式语法中,放括号表示字符范围。在方括号中可以包含多个字符,表示匹配其中任意一个字符。如果多个字符的编码顺序是连续的,可以仅指定开头和结尾字符,省略中间字符,仅使用连字符~表示。如果在方括号内添加脱字符^前缀,还可以表示范围之外的字符。
例如:
[abc]:查找方括号内任意一个字符。
[^abc]:查找不在方括号内的字符。
[0-9]:查找从 0 至 9 范围内的数字,即查找数字。
[a-z]:查找从小写 a 到小写 z 范围内的字符,即查找小写字母。
[A-Z]:查找从大写 A 到大写 Z 范围内的字符,即查找大写字母。
[A-z]:查找从大写 A 到小写 z 范围内的字符,即所有大小写的字母。
// [abc] 匹配abcy其中一个
var str = 'abcdy'
var r = /[abcy]/g
console.log(str.match(r)) //["a", "b", "c", "y"]
// [^d] 匹配不是d的全部字符
var str = 'abcdy'
var r = /[^d]/g
console.log(str.match(r)) //["a", "b", "c", "y"]
// [0-9] 匹配0至9的全部数字
var str = 'a1b2c6d8z0'
var r = /[0-9]/g
console.log(str.match(r)) //["1", "2", "6", "8", "0"]
// [^2-6] 匹配不是2至6的全部数字
var str = 'a1b2c6d8z0'
var r = /[^2-6]/g
console.log(str.match(r)) //["a", "1", "b", "c", "d", "8", "z", "0"]
// [a-z] 匹配小写字母a-z
var str = 'a1b2c6d8z0'
var r = /[a-z]/g
console.log(str.match(r)) //["a", "b", "c", "d", "z"]
// [A-Z] 匹配小写字母A-Z
var str = 'a1b2c6D8zZ0'
var r = /[A-Z]/g
console.log(str.match(r)) //["D","Z"]
// [A-z] 匹配大小写字母A-z 即匹配所以字母
var str = 'a1b2c6D8zZ0'
var r = /[A-z]/g
console.log(str.match(r)) //["a", "b", "c", "D", "z", "Z"]
//混用
var str = "abAcdez"; //字符串直接量
var r = /[Abc-z]/g; //字符A,b,以及从c~z之间的任意字符
console.log(str.match(r)) //["a", "b", "c", "D", "z", "Z"]
var str = '0afg 0acb 0ddd 1acb 10acccc'
var r = /0a[a-z][a-z]/g //全局匹配四个字符,第一个为0,第二个为a,第三第四个位a-z之间中的一个
console.log(str.match(r)) //["0afg", "0acb", "0acc"]
选择匹配
选择匹配类似于 JavaScript 的逻辑与运算,使用竖线|描述,表示在两个子模式的匹配结果中任选一个
var str = '0afg 0acb 0ddd 1acb 10acccc aaff'
var r = /([0a]|[1a])a/g
var r2 = /(0afg)|(0acb)/g
console.log(str.match(r)) //["0a", "0a", "1a", "0a", "aa"]
console.log(str.match(r2)) //["0afg", "0acb"]
重复匹配
n+ 匹配任何包含至少一个 n 的字符串
n* 匹配任何包含零个或多个 n 的字符串
n? 匹配任何包含零个或一个 n 的字符串
n{x} 匹配包含 x 个 n 的序列的字符串
n{x,y} 匹配包含最少 x 个、最多 y 个 n 的序列的字符串
n{x,}匹配包含至少 x 个 n 的序列的字符串
//n+ 匹配任何包含至少一个n的字符串
var str = 'aaadfdfdfccffffffggggg2wwe22233a333'
var r = /f+/g
console.log(str.match(r)) //["f", "f", "f", "ffffff"]
//n* 匹配任何包含零个或多个n的字符串
var str = 'aaadfdf3dfccfff3'
var r = /f*3/g
console.log(str.match(r)) // ["f3", "fff3"]
//n? 匹配任何包含零个或一个n的字符串
var str = 'aaadfdfdfccfff3'
var r = /f?[0-9]/g
console.log(str.match(r)) //["f3"]
//n{x} 含匹配包含 x 个 n 的序列的字符串
var str = 'aaadfdfdfccfff3'
var r = /f{2}[a-f]/g
console.log(str.match(r)) //["fff"]
//n{x,y} 匹配包含最少 x 个、最多 y 个 n 的序列的字符串
var str = 'aaadfdfdfccfff3'
var r = /f{1,2}3/g
console.log(str.match(r)) //["ff3"]
//n{x,} 匹配包含至少 x 个 n 的序列的字符串
var str = 'aaadfdfdfccfff3'
var r = /f{1,}3/g
console.log(str.match(r)) //["fff3"]
惰性匹配
重复类量词都具有贪婪性,在条件允许的前提下,会匹配尽可能多的字符。 ?、{n} 和 {n,m} 重复类具有弱贪婪性,表现为贪婪的有限性。
*、+ 和 {n,} 重复类具有强贪婪性,表现为贪婪的无限性。
针对 6 种重复类惰性匹配的简单描述如下:
{n,m}?:尽量匹配 n 次,但是为了满足限定条件也可能最多重复 m 次。
{n}?:尽量匹配 n 次。
{n,}?:尽量匹配 n 次,但是为了满足限定条件也可能匹配任意次。
??:尽量匹配,但是为了满足限定条件也可能最多匹配 1 次,相当于 {0,1}?。
+?:尽量匹配 1 次,但是为了满足限定条件也可能匹配任意次,相当于 {1,}?。
*? :尽量不匹配,但是为了满足限定条件也可能匹配任意次,相当于 {0,}?。
边界量词
^ 匹配开头,在多行检测中,会匹配一行的开头
$ 匹配结尾,在多行检测中,会匹配一行的结尾
var str = "https://www.baidu.com"
var r = /\w+$/g
console.log(str.match(r)) //["com"]
var r = /^\w+/g
console.log(str.match(r)) //["https"]
声明词量
声明表示条件的意思。声明词量包括正向声明和反向声明两种模式。
1.正向声明
指定匹配模式后面的字符必须被匹配,但又不返回这些字符。语法格式如下:
匹配模式 (?= 匹配条件)
声明包含在小括号内,它不是分组,因此作为子表达式。
var str = "A2B1"
var r = /\D(?=1)/g //查找非数字,且下一位为1的字符
console.log(str.match(r)) //["B"]
2.反向声明
与正向声明匹配相反,指定接下来的字符都不必被匹配。语法格式如下:
匹配模式(?! 匹配条件)
var r = /\D(?!1)/g //查找非数字,且下一位不为1的字符
console.log(str.match(r)) //["A"]
子表达式
使用小括号可以对字符模式进行任意分组,在小括号内的字符串表示子表达式,也称为子模式。子表达式具有独立的匹配功能,保存独立的匹配结果;同时,小括号后的量词将会作用于整个子表达式。
通过分组可以在一个完整的字符模式中定义一个或多个子模式。当正则表达式成功地匹配目标字符串后,也可以从目标字符串中抽出与子模式相匹配的子内容。
反向引用
在字符模式中,后面的字符可以引用前面的子表达式。实现方法如下: + 数字 数字指定了子表达式在字符模式中的顺序。如“\1”引用的是第 1
个子表达式,“\2”引用的是第 2 个子表达式。
var str = 'A1A2A33'
var r = /(\D)(\d)\1/g //\1为引用了(\D)子表达式
console.log(str.match(r)) //["A1A"] 引用后的值也是一样的
禁止引用
反向引用会占用一定的系统资源,在较长的正则表达式中,反向引用会降低匹配速度。如果分组仅仅是为了方便操作,可以禁止反向引用。
实现方法:在左括号的后面加上一个问号和冒号
var str = '226a336a'
var r = /(?:[0-9])\1/g
console.log(str.match(r)) //null
非引用型分组必须使用子表达式,但是又不希望存储无用的匹配信息,或者希望提高匹配速度来说,是非常重要的方法
修饰符
// i 执行对大小写不敏感的匹配。
var str = 'aA'
var r1 = /a+/
var r2 = /a+/i
console.log(str.match(r1)) // "a"
console.log(str.match(r2)) // "aA"
// g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
var str = "aaa"
var r1 = /a/
var r2 = /a/g
console.log(str.match(r1)) //"a"
console.log(str.match(r2)) //["a", "a", "a"]
// m 执行多行匹配。
var str="This is an\nantzone good";
var r1=/^a/
var r2=/^a/m
console.log(str.match(r1)); //null
console.log(str.match(r2)); //"a"
//修饰符连用
var str = "\naa"
var r1 = /A/
var r2 = /A/mig
console.log(str.match(r1)) //null
console.log(str.match(r2)) //["a", "a"]
RegExp
RegExp是正则表达式的构造函数,用于构建一共正则对象。他有两个常用的方法
1.test
用于检测字符串是否复核匹配的模式
var s = "1a2b3c"
var r = new RegExp(/\w/,"g")
console.log(r.test(s)) //true
2.exec
用于找出符合条件的字符。但是一次只按符合匹配模式的索引找一个结果 。
var s = 'abcde'
var r = new RegExp(/\w/,"g")
console.log(r.exec(s)) //a
console.log(r.exec(s)) //b
console.log(r.exec(s)) //c