概念
正则表达式是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象。这些模式被用于 RegExp 的 exec 和 test 方法, 以及 String 的 match、matchAll、replace、search 和 split 方法。
创建正则表达式
两种方法:字面量方式、构造函数方式
//字面量方式,其由包含在斜杠之间的模式组成,如下所示:
var re = /ab+c/;
//构造函数方式,调用RegExp对象的构造函数,如下所示:
var re = new RegExp("ab+c");
正则表达式中的特殊字符
\ 做为转意,即通常在"\"后面的字符不按原来意义解释,如/b/匹配字符"b",当b前面加了反斜杆后/\b/,转意为匹配一个单词的边界。
-或-
对正则表达式功能字符的还原,如"*"匹配它前面元字符0次或多次,/a*/将匹配a,aa,aaa,加了"\"后,/a\*/将只匹配"a*"。
^ 匹配一个输入或一行的开头,/^a/匹配"an A",而不匹配"An a"
$ 匹配一个输入或一行的结尾,/a$/匹配"An a",而不匹配"an A"
* 匹配前面元字符0次或多次,/ba*/将匹配b,ba,baa,baaa
+ 匹配前面元字符1次或多次,/ba*/将匹配ba,baa,baaa
? 匹配前面元字符0次或1次,/ba*/将匹配b,ba
(x) 匹配x保存x在名为$1...$9的变量中
x|y 匹配x或y
{n} 精确匹配n次
{n,} 匹配n次以上
{n,m} 匹配n-m次
[xyz] 字符集(character set),匹配这个集合中的任一一个字符(或元字符)
[^xyz] 不匹配这个集合中的任何一个字符
[\b] 匹配一个退格符
\b 匹配一个单词的边界
\B 匹配一个单词的非边界
\cX 这儿,X是一个控制符,/\cM/匹配Ctrl-M
\d 匹配一个字数字符,/\d/ = /[0-9]/
\D 匹配一个非字数字符,/\D/ = /[^0-9]/
\n 匹配一个换行符
\r 匹配一个回车符
\s 匹配一个空白字符,包括\n,\r,\f,\t,\v等
\S 匹配一个非空白字符,等于/[^\n\f\r\t\v]/
\t 匹配一个制表符
\v 匹配一个重直制表符
\w 匹配一个可以组成单词的字符(alphanumeric,这是我的意译,含数字),包括下划线,如[\w]匹配"$5.98"中的5,等于[a-zA-Z0-9]
\W 匹配一个不可以组成单词的字符,如[\W]匹配"$5.98"中的$,等于[^a-zA-Z0-9]。
正则表达式的直接量字符
字符 匹配
________________________________字母数字字符 自身
\ f 换页符
\ n 换行符
\ r 回车
\ t 制表符
\ v 垂直制表符
\ / 一个 / 直接量
\ \ 一个 \ 直接量
\ . 一个 . 直接量
\ * 一个 * 直接量
\ + 一个 + 直接量
\ ? 一个 ? 直接量
\ | 一个 | 直接量
\ ( 一个 ( 直接量
\ ) 一个 ) 直接量
\ [ 一个 [ 直接量
\ ] 一个 ] 直接量
\ { 一个 { 直接量
\ } 一个 } 直接量
\ XXX 由十进制数 XXX 指 定的ASCII码字符
\ Xnn 由十六进制数 nn 指定的ASCII码字符
\ cX 控制字符^X. 例如, \cI等价于 \t, \cJ等价于 \n___________________________________________________
如果想在正则表达式中使用特殊的标点符号,必须在它们之前加上一个 "\" .
g 全局匹配模式 /g 用法
代码如下:
1 2 3 4 5 6 |
|
在创建正则表达式对象时如果使用了“g”标识符或者设置它了的global属性值为ture时,那么新创建的正则表达式对象将使用模式对要将要匹配的字符串进行全局匹配。在全局匹配模式下可以对指定要查找的字符串执行多次匹配。每次匹配使用当前正则对象的lastIndex属性的值作为在目标字符串中开始查找的起始位置。lastIndex属性的初始值为0,找到匹配的项后lastIndex的值被重置为匹配内容的下一个字符在字符串中的位置索引,用来标识下次执行匹配时开始查找的位置,如果找不到匹配的项lastIndex的值会被设置为0。当没有设置正则对象的全局匹配标志时lastIndex属性的值始终为0,每次执行匹配仅查找字符串中第一个匹配的项。可以通下面的代码来查看在执行匹配相应的lastIndex 属性的值,代码如下:
1 2 3 4 5 6 7 8 9 10 |
|
正则表达式常用方法
校验数据
test(字符串)
测试字符是否满足正则表达式规则,如果测试到有,则返回true;没有则返回flase
语法:正则表达式.test(字符串) 正则表达式提供的方法
var reg=/[123]/
var str='1'
var result=reg.test(str)
console.log(result)//flase
search(正则表达式)
search() 方法执行正则表达式和 String 对象之间的一个搜索匹配。
语法:字符串.search(正则表达式) 字符串提供的方法
var reg=/\d/ //匹配阿拉伯数字
var str="abcdefg3sgbh"
var res=str.search(reg)
console.log(res) //7
//验证方法 找到返回下标 找不到返回-1
//在字符串中找到满足正则表达式的那一部分
区别:
.test()方法是正则表达式提供的,.search()是字符串提高的,
.test()方法返回布尔值,search()返回下标
提取数据
正则表达式.exec(字符串)
exec() 方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null。 正则表达式提供的方法
var reg=/\d/
var str="abcd456efg"
var res=reg.exec(str)
console.log(res)//返回一个数组,内容是4
//字符串中满足正则表达式的部分提取出来
//遇到满足条件的就返回,所以只返回4
字符串.match(正则表达式)
match() 方法检索返回一个字符串匹配正则表达式的结果。 字符串提供的方法
var reg=/\d/
var str="abcd456efg"
var res=str.match(reg) //字符串中满足表达式的部分提取出来
console.log(res)
区别:
正则表达式.exec(字符串),正则表达式提供的方法
字符串.match(正则表达式) 字符串的方法
相同:
都返回一个数组,只要匹配到符合规则的数据就返回
替换数据
字符串.replace(正则表达式,新的内容)
replace() 方法返回一个由替换值(replacement)替换部分或所有的模式(pattern)匹配项后的新字符串。模式可以是一个字符串或者一个正则表达式,替换值可以是一个字符串或者一个每次匹配都要调用的回调函数。如果pattern是字符串,则仅替换第一个匹配项。字符串提供的方法
var reg=/\d/
var str="11123bcd"
var res=str.replace(reg,"a") //将数字换为a
console.log(res)//a1123bcd 只要匹配到符合规则的就返回
断言
范围类
在[]组成的类内部是可以连写的
let text = 'a1B2d3X4Z5'
let reg=/[a-zA-Z]/
text.replace(reg,'Q')//Q1Q3Q4Q5
字符类
字符类取反
很多时候碰到这么一种情况,即不想匹配某些字符,其他都匹配。此时,可以使用字符类取反——使用元字符^,创建反向类,即不属于某类的内容。
[^abc]表示不是字符a或b或c的内容
1
let reg=/[^abc]/g
let text='a1b2c3d4e5'
console.log(text.replace(reg,'X')) //输出aXbXcXdXeX
修饰符
在正常情况下,正则匹配到第一个匹配项则停止,并且默认大小写敏感,如果想修改默认选项,则需要修饰符。
g:global全文搜索
var reg=new RegExp('l');
var a='hello'.replace(reg,'f')
console.log(a)//输出结果为:heflo
var reg=new RegExp('l','g');//加上g标签表示全文搜索
var a='hello'.replace(reg,'f')
console.log(a)//输出结果为:heffo (所有的 l 都换成了 f )
i:ignore case 忽略大小写
var reg=new RegExp('l','g');
var a='helloHELLO'.replace(reg,'f')
console.log(a)//输出结果为:heffoHELLO
var reg=new RegExp('l','gi');//加上i标签表示忽略大小写
var a='helloHELLO'.replace(reg,'f')
console.log(a)//输出结果为:heffoHEffO (大写和小写的l都被替换了)
m:multiple lines 多行搜索
var reg=new RegExp('od')
var str='so good\n so good'
var result=str.replace(reg,'hi')
console.log(result)
//结果为:
so gohi
so good
//只给第一行匹配了
var reg=new RegExp('od','gm')//加上m标签表示多行匹配
var str='so good\n so good'
var result=str.replace(reg,'hi')
console.log(result)
//结果为:
so gohi
so gohi
其他标志符
s:允许 . 匹配换行符。
u:使用unicode码的模式进行匹配。
y:执行“粘性(sticky)”搜索,匹配从目标字符串的当前位置开始。
量词符
贪婪模式
之前说了正则表达式的量词,但量词会带来一个到底匹配哪个的问题
例如:
var str="12345678"
var reg=/\d{3,6}/g
str.replace(reg,'X') //X78
可以看到结果是将123456 六个数字替换成了X,所以我们可以得到,正常模式下,正则表达式会尽可能多的匹配。正常情况下,正则表达式采用贪婪模式,即,尽可能多的匹配。
非贪婪模式
一但成功匹配不再继续尝试,这就是非贪婪模式。
只需要在量词后加上?即可
var str="12345678"
var reg=/\d{3,6}?/g
str.replace(reg,'X') //X45678
分组
在使用正则表达式的时候会想要匹配一串字符串连续出现多次的情况,使用()可以达到分组的功能
例如:(hello){3}
使用符号 | (或)实现选择的功能
例如:
var str='12341235'
let reg=/123(4|5)/g
//1234 1235二选一
反向引用
将一种格式的时间字符串:yyyy-MM-DD转为MM/DD/yyyy类型格式字符串。
由于年月日是不固定的,没法直接转换为固定数值。这时我们可以使用反向引用解决这个问题。
利用$n,n代表着分组的序号,序号是从1开始的。
例如:
let text='2022-02-23'
let reg=/(\d{4})-(\d{2})-(\d{2})/
let res=text.replace(reg,'$3/$2/$1')//将yyyy-MM-DD转换为MM/DD/yyyy
console.log(res)
常用
正数匹配
/*
* 只能输入正数
* */
export const positiveNumber = (num) => {num = num + ''num = num.replace(/[^\d.]/g, "");// 只保留两个小数num = num.replace(/^(\-)*(\d+)\.(\d+).*$/, '$1$2.$3');return num
}console.log(positiveNumber(-99.96666))
console.log(positiveNumber('3numb'))
/*** 验证电子邮箱格式*/
function email(value) {return /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(value);
}/*** 验证手机格式*/
function mobile(value) {return /^1[3-9]\d{9}$/.test(value)
}/*** 验证URL格式*/
function url(value) {return /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w-.\/?%&=]*)?/.test(value)
}/*** 验证日期格式*/
function date(value) {return !/Invalid|NaN/.test(new Date(value).toString())
}/*** 验证ISO类型的日期格式*/
function dateISO(value) {return /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value)
}/*** 验证十进制数字*/
function number(value) {return /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value)
}/*** 验证整数*/
function digits(value) {return /^\d+$/.test(value)
}/*** 验证身份证号码*/
function idCard(value) {return /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)
}/*** 是否车牌号*/
function carNo(value) {// 新能源车牌const xreg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF]$)|([DF][A-HJ-NP-Z0-9][0-9]{4}$))/;// 旧车牌const creg = /^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳]{1}$/;if (value.length === 7) {return creg.test(value);} else if (value.length === 8) {return xreg.test(value);} else {return false;}
}