创建形式
-
正则表达式有两种定义方式,一种是通过以/开头和/结束的字符串字面量,另一种是通过new和RegExp关键字来生成
// 构造函数创建 const regexp = new RegExp("内容", "修饰符") // 直接创建 - 字面量模式 const regexp = /.../
元字符
\d
:一位数字\D
:除数字外的任意字符\w
:数字、字母和下划线\W
:除数字、字母和下划线以外的字符\s
:表示空白符,包括空格、水平制表符、垂直制表符、换行符、回车符、换页符\S
:非空白字符.
:通配符,除换行外,可表示任意字符\r
:回车符\n
:换行符\t
:制表符\f
:换页符\v
:垂直制表符\p
:检测字符属性[]
:原子表,其中.
+
()
不被转义,不用反斜杠()
:原子组
使用时要被转义的元字符:(、[ 、{、\、^、$、** 、?、*、+、.、)、]、}**
字符属性(统一大写,写于\p
后边)
{P}
:标点字符{L}
:字母{M}
:标记符号(一般不会单独出现){Z}
:分隔符(比如空格、换行等){S}
:符号(比如数学符号、货币符号等){N}
:数字(比如阿拉伯数字、罗马数字等){C}
:其他字符{sc=xxx}
:指定语言系统
量词
{m,}
:至少出现m次{m}
:出现m次,等价于{m,m}{m,n}
:至少出现m次,最多出现n次?
:对问号前一个字母或元素进行处理 - 出现0次或一次,等价于{0,1}+
:至少出现一次,等价于{1,}*
:出现任意次,等价于{0,}?的妙用(禁止贪婪)
:/\d{3,6}
/g会匹配尽可能多满足要求的字符,/\d{3,6}?/g
会匹配最少的满足要求的字符,就是说3-6个范围内的数字都会被匹配,但是如果先匹配了3个就不会继续往下匹配了,可以加**
+
{}
?
后边,取区间最小值
位置
^
:匹配开头,若放在原子表里,表示取反$
:匹配结尾,多行匹配中匹配行末尾\b
:匹配单词边界,匹配\w和\W之间的位置,比如’123w_1 wei.123’这个字符串’123w_1’,’wei’,’123’属于3个单词,这3个单词的开头和结尾的位置就属于单词边界\B
:非单词边界,除了上面的那些位置都是非单词边界
断言
(?=内容)
:匹配内容后边是内容
的对应内容值,不是组(?<=内容)
:匹配内容前边是内容
的对应内容值,不是组(?!内容)
:匹配内容后边不是内容
的对应内容值,不是组(?<!内容)
:匹配内容前边不是内容
的对应内容值,不是组
修饰符
g
:全局查找s
:忽略换行符i
:不区分大小写m
:多行查找u
:Unicode模式,正确处理四个字节(宽字节)的UTF-16编码y
:粘附模式,从零开始(通过设置lastIndex来指定开始位置),若匹配到了就继续匹配,直到下一个匹配值不是时,停止匹配,在一定程度上节省性能
原子组
- 用
()
框起来的内容代表分组,例如需匹配连续出现的abc,就需要使用/(abc)+/
- 原子组中的
|
代表或者关系,例如(p1|p2)
可代表匹配模式p1或者模式p2 - 引用分组(捕获组):
- 添加括号的分组可以被引用
- 在正则表达式中还可以使用
\1
,\2
,\3
等来引用前面的分组 -
正则表达式
/\d{4}(-|/|.)\d{2}\1\d{2}/
中的\1
代表(-|/|.)
这个分组的匹配结果,即前面是-
后面也是-
,前面是/
后面也是/
,前面是.
后面也是.
/\d{4}(-|\/|\.)\d{2}(-|\/|\.)\d{2}/ //匹配2021/01.31 2021/01/31 2021-01-31 2021.01.31等-/.的随意组合 /\d{4}(-|\/|\.)\d{2}\1\d{2}/ // 只匹配2021/01/31 2021-01-31 2021.01.31这三种
- 非捕获分组:
- 引用分组可以通过
$1
或/1
取到为捕获型分组,非捕获型分组只用来分组但不可取,非捕获分组使用(?:)
?:
写在组的最前方,表示对该组不进行记录,故没有该组的值- 注:使用
.match()
来匹配时,不加全局搜索 - 使用
exec()
匹配时,可以用全局
- 引用分组可以通过
const string = "ababa abbb ababab"
string.match(/(?:ab)+/g) // ['abab', 'ab', 'ababab']
RegExp.$1 // ''
string.match(/(ab)+/g) // ['abab', 'ab', 'ababab']
RegExp.$1 // 'ab'
?<组别名>
:- 写在组的开始,给组起别名使用时,直接写对应的
$<别名>
就可以获取
- 写在组的开始,给组起别名使用时,直接写对应的
转义:有特殊意义的符号需要进行转义,如 . / 等,加 \ 进行转义
特殊符号
- $`:
- 正则
- 构造函数属性
.leftContext
的简写- 第一次匹配内容前面的内容
- 字符串(
.replace()
仅用于字符型替换)- 匹配内容前面的值,用于替换当前匹配到的值
- 正则
$'
:- 正则
- 构造函数属性
.rightContext
的简写- 获取匹配到的内容后边的内容
- 字符串(
.replace()
仅用于字符型替换)- 匹配内容后边的值,用于替换当前匹配到的值
- 正则
$&
:- 正则
- 构造函数属性
.lastMatch
简写- 最后匹配的内容
- 字符串(
.replace()
仅用于字符型替换)- 匹配到的内容
- 正则
$_
:正则属性- 构造函数属性
.input
的简写- 最后搜索的字符串
$+
:正则属性- 构造函数属性
.lastParen
的简写- 最后匹配到的捕获组值,若无原子组,则返回空
- 可以通过
$1
$2
$3
$4
…等来获取指定位置的组
$$
:字符串(.replace()
仅用于字符型替换)$
值
$n
:字符串(.replace()
仅用于字符型替换)- 匹配第n个捕获组字符串,n取值为1~9
- 若无组,则直接输出
$n
$nn
:字符串(.replace()
仅用于字符型替换)- 匹配第nn个捕获组字符串,nn取值为01~99
const patten = /(a)t/igs
const src = 'bat, aat, cat, vsat'
// 正则
if (patten.test(src)) {
console.log(RegExp.$_)
console.log(RegExp.input) // bat, aat, cat, vsat
console.log(RegExp["$`"])
console.log(RegExp.leftContext) // b
console.log(RegExp["$'"])
console.log(RegExp.rightContext) // , aat, cat, vsat
console.log(RegExp["$&"])
console.log(RegExp.lastMatch) // at
console.log(RegExp["$+"]) // a
console.log(RegExp.$1) // a
}
// 字符串
console.log(src.replace(patten, "$1")) // ba,aa, ca, vsa
console.log(src.replace(patten, "$01")) // ba,aa, ca, vsa
console.log(src.replace(patten, "$$")) // b$,a$, c$, vs$
console.log(src.replace(patten, "$`")) // bb,abat,a, cbat,aat, c, vsbat,aat, cat, vs
console.log(src.replace(patten, "$1'")) // b,aat, cat, vsat,a, cat, vsat, c, vsat, vs
console.log(src.replace(patten, "$&")) // bat,aat, cat, vsat
src.replace(patten, (a,b,c,d,e)=> {
// 基础三个参数,后续每个组别为一个中间参数
// 第一个参数是匹配到的值
// 倒数第二个参数是匹配到的值的位置(从零开始计算)
// 最后一个参数是全字符串
// 中间的都是组别匹配到的值
console.log(a) // at ...
console.log(b) // a ...
console.log(c) // 1 ...
console.log(d) // bat,aat, cat, vsat, aaa ...
console.log(e) // undefined ...
})
正则属性及方法
属性
lastIndex
:整数,源字符串中,下一次搜索的开始位置,默认始终为0- 当使用全局匹配时,该属性的值为匹配到的
- 必须使用正则的方法才有用,再一个数组中
.match()
中是无效的 - 若没有使用全局的匹配,返回值一直是第一个匹配到的位置
- 使用全局匹配时,每次返回匹配到的下一个的位置
- 要先调用对应的正则匹配方法,再调这个属性,否则只会返回零
- 若没有匹配的的正则值,则也返回零
const str = 'asdfavghanh' const regular = /a/g regular.exec(str) // 返回第一个匹配到的值 regular.lastIndex // 返回第一个匹配到的值的位置 regular.exec(str) // 返回第二个匹配到的值 regular.lastIndex // 返回第二个匹配到的值的位置 regular.exec(str) // 返回第累计的下一个匹配到的值 regular.lastIndex // 返回匹配到的值对应的位置
global
:布尔值,是否设置g
标记ignoreCase
:布尔值,是否设置i
标记unicode
:布尔值,是否设置u
标记sticky
:布尔值,是否设置y
标记multiline
:布尔值,是否设置m
标记dotAll
:布尔值,是否设置s
标记source
:正则表达式中的字面量字符串,没用开始和结束的斜杠flags
:正则表达式的标记字符串,没有斜杠
const patten = /at/igs
console.log(patten.global) // true
console.log(patten.ignoreCase) // true
console.log(patten.unicode) // false
console.log(patten.sticky) // false
console.log(patten.multiline) // false
console.log(patten.dotAll) // true
console.log(patten.source) // at
console.log(patten.flags) // igs
方法
.test()
- 语法:
正则.test(字符串)
- 在字符串中搜索符合正则的内容,搜索到返回
true
- 搜索失败就返回
false
regular.test(str)
- 语法:
.exec()
- 语法:
正则.exec(字符串)
- 只接收一个参数
- 找到匹配项,返回包含第一个的详细信息数组,不管是不是全局匹配,都只会得到一个详细数组值
- 返回数组的第一个值为匹配项,其余为原子组的捕获值
- 数组具有额外属性
index
input
index
:匹配到的值的起始位置input
:查找的整体字符串
- 不加全局,永远匹配第一个,加全局,重复调用,每次匹配下一个
- 找不到,则返回null
regular.exec(str) const str = '2021-01-31' const reg1 = /\d{4}-\d{2}-\d{2}/ const reg2 = /(\d{4})-(\d{2})-(\d{2})/ str.match(reg1) // ['2021-01-31', index: 0, input: '2021-01-31', groups: undefined] str.match(reg2) // ['2021-01-31', '2021', '01', '31', index: 0, input: '2021-01-31', groups: undefined] console.log(RegExp.$1) // '2021'
- 语法:
字符串的方法(正则部分)
.search()
- 语法:
字符串.search(正则)
- 在字符串中搜索符合规则的内容,搜索成功就返回第一个值的位置
- 匹配失败时返回-1
str.search(regular)
- 语法:
.match()
- 语法:
字符串.match(正则)
- 查找符合正则的字符串
- 一般加全局搜索
- 不加全局收索时返回值和
.exec()
返回值一样,匹配的第一个匹配值及捕获组的值- 第一个元素是整体匹配结果
- 第二个及之后的是各个分组匹配的内容
- 后边有俩额外参数
- 加全局搜索时,返回匹配到的所有值(仅匹配到的值)
- 返回数据类型为数组
str.match(regular)
- 语法:
.replace()
- 语法:
字符串.replace(正则,新的字符串/回调函数)
- 和
.match()
方法一样,搜索符合规则的内容,替换成对应的字符串。 - 返回替换后的内容。
- 第二个参数可以是回调函数(基础三个参数,后续每个组别为一个中间参数)
- 第一个参数是匹配到的值
- 倒数第二个参数是匹配到的值的位置(从零开始计算)
- 最后一个参数是全字符串
- 中间的都是组别匹配到的值
// 字符串型替换 str.replace(regular, '') // 函数型替换 str.replace(regular, (v,r,s) => {})
- 语法:
使用示例及常用正则
-
常用正则
// 提取数字 - 获得数组 let key = str.match(/\d/g) // 提取汉字 - 获得数组 let text = str.match(/[^ -~]/g) // 提取字母 - 获取数组 let value = str.match(/[a-z]/ig); // 获取指定区域中的内容 let str = /<style>[\s\S]*<\/style>/.exec('指定字符串') // 匹配标点符号,修饰符u必须带 let str = str.match(/\p{P}/gu) // 匹配字母,修饰符u必须带 let str = str.match(/\p{L}/gu) // 匹配汉字,修饰符u必须带 let str = str.match(/\p{sc=Han}/gu)
常用正则
// 非负整数:
^\d+$
// 正整数:
^[0-9]*[1-9][0-9]*$
// 非正整数:
^((-\d+)|(0+))$
// 负整数:
^-[0-9]*[1-9][0-9]*$
// 整数:
^-?\d+$
// 非负浮点数:
^\d+(\.\d+)?$
// 正浮点数 :
^((0-9)+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)$
// 非正浮点数:
^((-\d+\.\d+)?)|(0+(\.0+)?))$
// 负浮点数:
^(-((正浮点数正则式)))$
// 英文字符串:
^[A-Za-z]+$
// 英文大写串:
^[A-Z]+$
// 英文小写串:
^[a-z]+$
// 英文字符数字串:
^[A-Za-z0-9]+$
// 英数字加下划线串:
^\w+$
// E-mail地址:
^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$
// URL:
^[a-zA-Z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\s*)?$
// OR
// ^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&_~`@[\]\':+!]*([^<>\"\"])*$
// 邮政编码:
^[1-9]\d{5}$
// 中文:
^[\u0391-\uFFE5]+$
// 电话号码:
^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$
// 手机号码:
^((\(\d{2,3}\))|(\d{3}\-))?13\d{9}$
// 双字节字符(包括汉字在内):
^\x00-\xff
// 匹配首尾空格:
(^\s*)|(\s*$)(像vbscript那样的trim函数)
// 匹配HTML标记:
<(.*)>.*<\/\1>|<(.*) \/>
// 匹配空行:
\n[\s| ]*\r
// 提取信息中的网络链接:
(h|H)(r|R)(e|E)(f|F) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?
// 提取信息中的邮件地址:
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
// 提取信息中的图片链接:
(s|S)(r|R)(c|C) *= *('|")?(\w|\\|\/|\.)+('|"| *|>)?
// 提取信息中的IP地址:
(\d+)\.(\d+)\.(\d+)\.(\d+)
// 提取信息中的中国手机号码:
(86)*0*13\d{9}
// 提取信息中的中国固定电话号码:
(\(\d{3,4}\)|\d{3,4}-|\s)?\d{8}
// 提取信息中的中国电话号码(包括移动和固定电话):
(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}
// 提取信息中的中国邮政编码:
[1-9]{1}(\d+){5}
// 提取信息中的浮点数(即小数):
(-?\d*)\.?\d+
// 提取信息中的任何数字 :
(-?\d*)(\.\d+)?
// IP:
(\d+)\.(\d+)\.(\d+)\.(\d+)
// 电话区号:
/^0\d{2,3}$/
// 腾讯QQ号:
^[1-9]*[1-9][0-9]*$
// 帐号(字母开头,允许5-16字节,允许字母数字下划线):
^[a-zA-Z][a-zA-Z0-9_]{4,15}$
// 中文、英文、数字及下划线:
^[\u4e00-\u9fa5_a-zA-Z0-9]+$
// 匹配中文字符的正则表达式:
[\u4e00-\u9fa5]
// 匹配双字节字符(包括汉字在内):
[^\x00-\xff]
// 匹配空行的正则表达式:
\n[\s| ]*\r
// 匹配HTML标记的正则表达式:
/<(.*)>.*<\/\1>|<(.*) \/>/
// sql语句:
^(select|drop|delete|create|update|insert).*$
// 匹配首尾空格的正则表达式:
(^\s*)|(\s*$)
// 匹配Email地址的正则表达式:
\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*