1 LocalStorage
2 SessionStorage
3 正则表达式的使用
4 正则表达式常见规则
5 正则练习-歌词解析
6 正则练习-日期格式化
Storage-Storage的基本操作
// storage基本使用 // 1.token的操作 let token = localStorage.getItem("token") if (!token) { console.log("从服务器获取token") token = "coderwhytokeninfo" localStorage.setItem("token", token) } // 2.username/password的操作 let username = localStorage.getItem("username") let password = localStorage.getItem("password") if (!username || !password) { console.log("让用户输入账号和密码") username = "coderwhy" password = "123456" // 将token/username/password保存到storage localStorage.setItem("username", username) localStorage.setItem("password", password) } // 3.后续的操作 console.log(token) console.log(token.length) console.log(token + " 哈哈哈")
Storage-local和session区别
localstorage是永久保存的,seessionstorage是暂时存储的,也就是说只要这次浏览器页面没关闭,就一直存在,sessionstorage的作用是用在一次会话,有a链接跳转其他页面时进行数据传递用的,比起localstorage使用起来会更舒服。
但是如果a链接使用的target是self,那sessionstorage是查找不到的
<body> <a href="./static/about.html" target="_blank">关于</a> <script> // 1.验证一: 关闭网页 // 1.1.localStorage的存储保持 // localStorage.setItem("name", "localStorage") // 1.2.sessionStorage的存储会消失 // sessionStorage.setItem("name", "sessionStorage") // 2.验证二: 打开新的网页 // localStorage.setItem("info", "local") // sessionStorage.setItem("info", "session") // 3.验证三: 打开新的页面, 并且是在新的标签中打开 localStorage.setItem("infoTab", "local") sessionStorage.setItem("infoTab", "session") </script> </body>
Storage-Storage其他方法
开发技巧,有相同的变量名称的时候,我们可以设置一个大写字母组成的字符串常量。
const ACCESS_TOKEN = "token" console.log(localStorage.length) // 常见的方法: localStorage.setItem(ACCESS_TOKEN, "whytoken") console.log(localStorage.getItem(ACCESS_TOKEN)) // 其他方法 console.log(localStorage.key(0)) console.log(localStorage.key(1)) console.log(localStorage.removeItem("infoTab")) localStorage.clear()
Storage-Storage工具封装
封装了storage的方法,使得使用的时候能有自己想要的处理事件。
封装文件cache.js
class Cache { constructor(isLocal = true) { this.storage = isLocal ? localStorage: sessionStorage } setCache(key, value) { if (!value) { throw new Error("value error: value必须有值!") } if (value) { this.storage.setItem(key, JSON.stringify(value)) } } getCache(key) { const result = this.storage.getItem(key) if (result) { return JSON.parse(result) } } removeCache(key) { this.storage.removeItem(key) } clear() { this.storage.clear() } } const localCache = new Cache() const sessionCache = new Cache(false)
使用封装的代码
localCache.setCache("sno", 111) // storage本身是不能直接存储对象类型的 const userInfo = { name: "why", nickname: "coderwhy", level: 100, imgURL: "http://github.com/coderwhy.png" } // localStorage.setItem("userInfo", JSON.stringify(userInfo)) // console.log(JSON.parse(localStorage.getItem("userInfo"))) sessionCache.setCache("userInfo", userInfo) console.log(sessionCache.getCache("userInfo"))
RegExp-正则表达式的创建
i表示无论大小写,g表示全局的、全部的、m表示多行匹配
// 创建正则 // 1> 匹配的规则pattern // 2> 匹配的修饰符flags const re1 = new RegExp("abc", "ig") const re2 = /abc/ig // 我是注释
RegExp-正则表达式的演练
// 创建正则 const re1 = /abc/ig const message = "fdabc123 faBC323 dfABC222 A2324aaBc" // 1.使用正则对象上的实例方法 // 2.使用字符串的方法, 传入一个正则表达式 // 需求: 将所有的abc(忽略大小写)换成cba // const newMessage = message.replaceAll("abc", "cba") // console.log(newMessage) const newMessage = message.replaceAll(/abc/ig, "cba") console.log(newMessage) // 需求: 将字符串中数字全部删除 const newMessage2 = message.replaceAll(/\d+/ig, "") console.log(newMessage2)
RegExp-正则表达式的使用
1
// 创建正则 const re1 = /abc/ig const message = "fdabc123 faBC323 dfABC222 A2324aaBc" // 1.使用正则对象上的实例方法 // webpack -> loader -> test: 匹配文件名 // 正则 -> 拿到文件 -> loader操作 // 1.1.test方法: 检测某一个字符串是否符合正则的规则 // if (re1.test(message)) { // console.log("message符合规则") // } else { // console.log("message不符合规则") // } // 1.2.exec方法: 使用正则执行一个字符串 // const res1 = re1.exec(message) // console.log(res1) // 2.使用字符串的方法, 传入一个正则表达式 // 2.1. match方法: // const result2 = message.match(re1) // console.log(result2) // 2.2. matchAll方法 // 注意: matchAll传入的正则修饰符必须加g // const result3 = message.matchAll(re1) // // console.log(result3.next()) // // console.log(result3.next()) // // console.log(result3.next()) // // console.log(result3.next()) // for (const item of result3) { // console.log(item) // } // 2.3. replace/replaceAll方法 // 2.4. split方法 // const result4 = message.split(re1) // console.log(result4) // 2.5. search方法 const result5 = message.search(re1) console.log(result5) // 案例: 让用户输入的账号必须是aaaaa以上 // const inputEl = document.querySelector("input") // const tipEl = document.querySelector(".tip") // inputEl.oninput = function() { // const value = this.value // if (/^a{5,8}$/.test(value)) { // tipEl.textContent = "输入的内容符合规则要求" // } else { // tipEl.textContent = "输入的内容不符合规则要求, 请重新输入" // } // }
RegExp-正则规则-字符类
// 创建正则 const re1 = /abc/ig const message = "fdabc123 faBC323 dfABC222 A2324aaBc" // 1.使用正则对象上的实例方法 // webpack -> loader -> test: 匹配文件名 // 正则 -> 拿到文件 -> loader操作 // 1.1.test方法: 检测某一个字符串是否符合正则的规则 // if (re1.test(message)) { // console.log("message符合规则") // } else { // console.log("message不符合规则") // } // 1.2.exec方法: 使用正则执行一个字符串 // const res1 = re1.exec(message) // console.log(res1) // 2.使用字符串的方法, 传入一个正则表达式 // 2.1. match方法: // const result2 = message.match(re1) // console.log(result2) // 2.2. matchAll方法 // 注意: matchAll传入的正则修饰符必须加g // const result3 = message.matchAll(re1) // // console.log(result3.next()) // // console.log(result3.next()) // // console.log(result3.next()) // // console.log(result3.next()) // for (const item of result3) { // console.log(item) // } // 2.3. replace/replaceAll方法 // 2.4. split方法 // const result4 = message.split(re1) // console.log(result4) // 2.5. search方法 const result5 = message.search(re1) console.log(result5) // 案例: 让用户输入的账号必须是aaaaa以上 // const inputEl = document.querySelector("input") // const tipEl = document.querySelector(".tip") // inputEl.oninput = function() { // const value = this.value // if (/^a{5,8}$/.test(value)) { // tipEl.textContent = "输入的内容符合规则要求" // } else { // tipEl.textContent = "输入的内容不符合规则要求, 请重新输入" // } // }
RegExp-正则规则-锚点
const message = "My name is WHY." // 字符串方法 if (message.startsWith("my")) { console.log("以my开头") } if (message.endsWith("why")) { console.log("以why结尾") } // 正则: 锚点 if (/^my/i.test(message)) { console.log("以my开头") } if (/why\.$/i.test(message)) { console.log("以why结尾") } const re = /^coder$/ const info = "codaaaer" console.log(re.test(info)) // false
RegExp-正则规则-词边界
// \w const message = "My name! is WHY." // 需求: name, name必须是一个单独的词 // 词边界 if (/\bname\b/i.test(message)) { console.log("有name, name有边界") } // 词边界的应用 const infos = "now time is 11:56, 12:00 eat food, number is 123:456" const timeRe = /\b\d\d:\d\d\b/ig console.log(infos.match(timeRe))
RegExp-正则规则-转义
// 定义正则: 对.转义 const re = /\./ig const message = "abc.why" const results = message.match(re) console.log(results) // 特殊: / // const re2 = /\// // 获取到很多的文件名 // jsx -> js文件 const fileNames = ["abc.html", "Home.jsx", "index.html", "index.js", "util.js", "format.js"] // 获取所有的js的文件名(webpack) // x?: x是0个或者1个 const jsfileRe = /\.jsx?$/ // 1.for循环做法 // const newFileNames = [] // for (const filename of fileNames) { // if (jsfileRe.test(filename)) { // newFileNames.push(filename) // } // } // console.log(newFileNames) // 2.filter高阶函数 // const newFileNames = fileNames.filter(filename => jsfileRe.test(filename)) // console.log(newFileNames)
RegExp-正则规则-集合
// 手机号的规则: 1[3456789]033334444 const phoneStarts = ["132", "130", "110", "120", "133", "155"] const phoneStartRe = /^1[3456789]\d/ const filterPhone = phoneStarts.filter(phone => phoneStartRe.test(phone)) console.log(filterPhone) const phoneNum = "133888855555" const phoneRe = /^1[3-9]\d{9}$/ console.log(phoneRe.test(phoneNum)) // 了解: 排除范围 // \d -> [0-9] // \D -> [^0-9]
RegExp-正则规则-量词
// 1.量词的使用 const re = /a{3,5}/ig const message = "fdaaa2fdaaaaaasf42532fdaagjkljlaaaaf" const results = message.match(re) console.log(results) // 2.常见的符号: +/?/* // +: {1,} // ?: {0,1} // *: {0,} // 3.案例: 字符串的html元素, 匹配出来里面所有的标签 const htmlElement = "<div><span>哈哈哈</span><h2>我是标题</h2></div>" const tagRe = /<\/?[a-z][a-z0-9]*>/ig const results2 = htmlElement.match(tagRe) console.log(results2)
RegExp-正则规则-贪婪惰性
// 1.贪婪模式/惰性模式 const message = "我最喜欢的两本书: 《黄金时代》和《沉默的大多数》、《一只特立独行的猪》" // 默认.+采用贪婪模式 // const nameRe = /《.+》/ig // const result1 = message.match(nameRe) // console.log(result1) // 使用惰性模式 const nameRe = /《.+?》/ig const result1 = message.match(nameRe) console.log(result1)
RegExp-正则规则-捕获组
// 1.捕获组 const message = "我最喜欢的两本书: 《黄金时代》和《沉默的大多数》、《一只特立独行的猪》" // 使用惰性模式 const nameRe = /(?:《)(?<why>.+?)(?:》)/ig const iterator = message.matchAll(nameRe) for (const item of iterator) { console.log(item) } // 2.将捕获组作为整体 const info = "dfabcabcfabcdfdabcabcabcljll;jk;j" const abcRe = /(abc){2,}/ig console.log(info.match(abcRe))
RegExp-正则规则-或or
// 1.将捕获组作为整体 const info = "dfabcabcfabcdfdabcabcabcljcbacballnbanba;jk;j" const abcRe = /(abc|cba|nba){2,}/ig console.log(info.match(abcRe))
RegExp-正则练习-歌词解析
<body> <script src="./js/parse_lyric.js"></script> <script> /* currentTime: 2000 [00:00.000] 作词 : 许嵩 -> { time: 0, content: "作词 : 许嵩" } [00:01.000] 作曲 : 许嵩 -> { time: 1000, content: "作曲 : 许嵩" } [00:02.000] 编曲 : 许嵩 [00:22.240]天空好想下雨 */ const lyricString = "[00:00.000] 作词 : 许嵩\n[00:01.000] 作曲 : 许嵩\n[00:02.000] 编曲 : 许嵩\n[00:22.240]天空好想下雨\n[00:24.380]我好想住你隔壁\n[00:26.810]傻站在你家楼下\n[00:29.500]抬起头数乌云\n[00:31.160]如果场景里出现一架钢琴\n[00:33.640]我会唱歌给你听\n[00:35.900]哪怕好多盆水往下淋\n[00:41.060]夏天快要过去\n[00:43.340]请你少买冰淇淋\n[00:45.680]天凉就别穿短裙\n[00:47.830]别再那么淘气\n[00:50.060]如果有时不那么开心\n[00:52.470]我愿意将格洛米借给你\n[00:55.020]你其实明白我心意\n[00:58.290]为你唱这首歌没有什么风格\n[01:02.976]它仅仅代表着我想给你快乐\n[01:07.840]为你解冻冰河为你做一只扑火的飞蛾\n[01:12.998]没有什么事情是不值得\n[01:17.489]为你唱这首歌没有什么风格\n[01:21.998]它仅仅代表着我希望你快乐\n[01:26.688]为你辗转反侧为你放弃世界有何不可\n[01:32.328]夏末秋凉里带一点温热有换季的颜色\n[01:41.040]\n[01:57.908]天空好想下雨\n[01:59.378]我好想住你隔壁\n[02:02.296]傻站在你家楼下\n[02:03.846]抬起头数乌云\n[02:06.183]如果场景里出现一架钢琴\n[02:08.875]我会唱歌给你听\n[02:10.974]哪怕好多盆水往下淋\n[02:15.325]夏天快要过去\n[02:18.345]请你少买冰淇淋\n[02:21.484]天凉就别穿短裙\n[02:22.914]别再那么淘气\n[02:25.185]如果有时不那么开心\n[02:27.625]我愿意将格洛米借给你\n[02:30.015]你其实明白我心意\n[02:33.327]为你唱这首歌没有什么风格\n[02:37.976]它仅仅代表着我想给你快乐\n[02:42.835]为你解冻冰河为你做一只扑火的飞蛾\n[02:48.406]没有什么事情是不值得\n[02:52.416]为你唱这首歌没有什么风格\n[02:57.077]它仅仅代表着我希望你快乐\n[03:01.993]为你辗转反侧为你放弃世界有何不可\n[03:07.494]夏末秋凉里带一点温热\n[03:11.536]\n[03:20.924]为你解冻冰河为你做一只扑火的飞蛾\n[03:26.615]没有什么事情是不值得\n[03:30.525]为你唱这首歌没有什么风格\n[03:35.196]它仅仅代表着我希望你快乐\n[03:39.946]为你辗转反侧为你放弃世界有何不可\n[03:45.644]夏末秋凉里带一点温热有换季的颜色\n" // 一. 没有封装 // 1.根据\n切割字符串 const lyricLineStrings = lyricString.split("\n") // console.log(lyricLineStrings) // 2.针对每一行歌词进行解析 // [01:22.550]夏末秋凉里带一点温热有换季的颜色 const timeRe = /\[(\d{2}):(\d{2})\.(\d{2,3})\]/i const lyricInfos = [] for (const lineString of lyricLineStrings) { // 1.获取时间 const result = lineString.match(timeRe) if (!result) continue const minuteTime = result[1] * 60 * 1000 const secondTime = result[2] * 1000 const mSecondTime = result[3].length === 3? result[3]*1: result[3]*10 const time = minuteTime + secondTime + mSecondTime // 2.获取内容 const content = lineString.replace(timeRe, "").trim() // 3.将对象放到数组中 lyricInfos.push({ time, content }) } console.log(lyricInfos) // 二.封装工具: 解析歌词 // const lyricInfos = parseLyric(lyricString) // console.log(lyricInfos) </script>
RegExp-正则练习-时间格式化
<body> <h2 class="time"></h2> <script> // timestamp: 1659252290626 // yyyy/MM/dd hh:mm:ss // yyyy*MM*dd hh-mm-ss // dayjs/moment 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.正则和值匹配起来 const dateO = { "y+": date.getFullYear(), "M+": date.getMonth() + 1, "d+": date.getDate(), "h+": date.getHours(), "m+": date.getMinutes(), "s+": date.getSeconds() } // 3.for循环进行替换 for (const key in dateO) { const keyRe = new RegExp(key) if (keyRe.test(fmtString)) { const value = (dateO[key] + "").padStart(2, "0") fmtString = fmtString.replace(keyRe, value) } } return fmtString } // 某一个商品上架时间, 活动的结束时间 const timeEl = document.querySelector(".time") const productJSON = { name: "iPhone", newPrice: 4999, oldPrice: 5999, endTime: 1659252301637 } timeEl.textContent = formatTime(productJSON.endTime, "hh:mm:ss yyyy*MM*dd") </script> </body>
parse_lyric.js
function parseLyric(lyricString) {
// 1.根据\n切割字符串
const lyricLineStrings = lyricString.split("\n")
// console.log(lyricLineStrings)
// 2.针对每一行歌词进行解析
// [01:22.550]夏末秋凉里带一点温热有换季的颜色
const timeRe = /\[(\d{2}):(\d{2})\.(\d{2,3})\]/i
const lyricInfos = []
for (const lineString of lyricLineStrings) {
// 1.获取时间
const result = lineString.match(timeRe)
if (!result) continue
const minuteTime = result[1] * 60 * 1000
const secondTime = result[2] * 1000
const mSecondTime = result[3].length === 3? result[3]*1: result[3]*10
const time = minuteTime + secondTime + mSecondTime
// 2.获取内容
const content = lineString.replace(timeRe, "").trim()
// 3.将对象放到数组中
lyricInfos.push({ time, content })
}
return lyricInfos
}