什么是正则表达式
- 首先不用花大量时间,因为项目中只有很少的地方需要使用
- 所以基本的了解就可以
- 维基百科对正则表示式的解释
- regular expression,简写为regex,又称正则表示式、正则表示法
- 正则表示式使用单个字符串来描述,匹配一系列匹配某个句法规则的字符串
- 许多程序语言都支持利用正则表达式进行字符串操作
- 简单概括:正则表达式是一种字符串匹配利器,可以帮助我们搜索、获取、替代字符串
- JS中,使用RegExp类来创建,也有对应的字面量的方式
- 正则表达式主要有两部分组成:模式和修饰符
const re1 = new RegExp("hello", "i")
const re2 = /hello/i
正则表达式的使用方法
- JS中的正则表达式被用于RegExp的exec和test方法
- 也包括String的match、matchAll、replace、search和split方法
- 正则表达式的基本使用
// 创建正则
const re1 = /abc/ig
const message = "fdabc123 faBC321 dfABC AaaBc"
// 1.使用正则对象上的实例方法
// 2.使用字符串的方法,传入一个正则表达式
// 需求:将所有的abc换成cba,忽略大小写
// 只会替换第一个
// const newMessage = message.replaceAll("abc", "cba")
// console.log(newMessage);
const newMessage = message.replaceAll(/abc/ig, "cba")
console.log(newMessage)
// 需求:将字符串中数字全部删除
// \d表示数字,+表示多个,i表示忽略大小写,g表示全局
const newMessage2 = message.replaceAll(/\d+/ig,"")
console.log(newMessage2)
修饰符flag的作用
常见的修饰符:
- g:全部的
- i:忽略大小写
- m:多行匹配
规则 - 字符类
- 字符类是一个特殊的符号,匹配特定集中的任何符号
规则 - 锚点和词边界
- 符号 ^ 和 符号 $ :
- ^ 匹配文本开头
- $ 匹配文本末尾
- 词边界:
- \b是一种检查,就像^和$一样,它会检查字符串中的位置是否是词边界
- \b检查位置的一侧是否匹配\w,而另一侧则不匹配"\w"
// 词边界的应用
// 匹配时间
const infos = "now time is 11:56, 12:00, number is 123:456"
const timeRe = /\b\d\d:\d\d\b/ig
console.log(infos.match(timeRe))
规则 - 转义字符串
- 如果要把特殊字符作为常规字符来使用,需要对其进行转义:
- 只需要在它面前加个反斜杠;
- 常见的需要转义的字符:
- \ ^ $ . \ ? * + ( )
// 获取所有的js的文件(webpack)
// x?:x是0个或者1个
const jsfileRe = /\.jsx?$/
集合和范围
- 有时候我们只要选择多个匹配字符的其中之一就可以:
- 在方括号[…]中的几个字符或者字符类意味着“搜索给定的字符中的任意一个”
- 集合
- [eao]意味着查找3个字符中的任意一个
- 范围
- 方括号也可以包含字符范围
- [a-z]会匹配a到z的字母范围
- [0-9A-F]表示两个范围:它搜索一个字符,满足数字0到9或字母A到F
- \d 和 [0-9]相同
- \w 和 [a-zA-Z0-9]相同
- 排除范围
- [^…]
量词
- 数量{n}
- 确切的位数:{5}
- 某个范围的位数:{3,5}
- 缩写:
- +:代表一个或多个,相当于{1,}
- ?:代表0个或一个,相当于{0,1}。换句话说,它使得符号变得可选
- *:代表着0个或多个,相当于{0,},也就是说,这个字符可以多次出现或不出现
//匹配里面所有的标签
const htmlElement = `<div><span>hhh</span><h2>我是标签</h2></div>`
const tagRe = /<\/?[a-z][a-z0-9]*>/ig
const results2 = htmlElement.match(tagRe)
console.log(results2)
贪婪(Greedy) 和惰性(lazy)模式
- 如果我们有这样一个需求:匹配下面字符串中所有使用《》包裹的内容
- 默认情况下的匹配规则是查找到匹配的内容后,会继续向后查找,一直找到最后一个匹配的内容
- 这种匹配的方式,我们称之为贪婪模式
- 惰性模式中的量词与贪婪模式中的是相反的
- 只要获取到对应的内容后,就不再继续向后匹配
- 我们可以在量词后面加一个问号"?"来启动它
const message2 = "我最喜欢的两本书:《黄金时代》和 《沉默的大多数》"
// 默认使用.+采用贪婪模式
// const nameRe = /《.+》/ig
// const result1 = message.match(nameRe)
// console.log(result1)
// 使用惰性模式
const nameRe = /《.+?》/ig
const result1 = message.match(nameRe)
console.log(result1)
捕获组
- 模式的一部分可以用括号括起来(…),这称为"捕获组"
- 这有两个作用:
- 他允许将匹配的一部分作为结果数组中的单独项
- 可以遍历数组,将对应的单独项取出
- 它的另一个作用是将括号视为一个整体
- 他允许将匹配的一部分作为结果数组中的单独项
案例练习 - 时间格式化
function formatTime(timestamp,fmtString) {
// 1.将时间戳转成Date
const date = new Date(timestamp)
// 2.获取到值
// const year = date.getFullYear()
// const month = date.getMonth() + 1
// const day = date.getDate()
// const hour = date.getHours()
// const minute = date.getMinutes()
// const second = date.getSeconds()
// 3.创建正则
// const yearRe = /y+/
// const monthRe = /M+/
// 将2和3结合,正则和值匹配起来
const dateO = {
"y+": date.getFullYear(),
"M+":date.getMonth()+1,
"d+":date.getDate(),
"h+": date.getHours(),
"m+":date.getMinutes(),
"s+": date.getSeconds()
}
// for循环进行替换
for (const key in dateO) {
if(new RegExp(key).test(fmtString)) {
const value = (dateO[key] + "").padStart(2,"0")
fmtString = fmtString.replace(new RegExp(key), value)
}
}
return fmtString
}
// 从服务器获取的商品上架时间,活动的结束时间
const productJSON = {
name:"iPhone",
newPrice:49999,
oldPrice:59999,
endTime:1659252290626//时间戳
}
const timestamp = 1659252290626
let content = formatTime(productJSON.endTime,"yyyy/MM/dd hh:mm:ss")
console.log(content)