Storage, regular expressions

1 LocalStorage

2 SessionStorage

3 Use of regular expressions

4 Common rules for regular expressions

5 Regular Exercise-Lyrics Analysis

6 Regular Exercise-Date Formatting

Basic operations of 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 + " 哈哈哈")

The difference between Storage-local and session

Localstorage is permanently stored, and sessionstorage is temporarily stored, which means that it will always exist as long as the browser page is not closed this time. Sessionstorage is used in a session, and is used for data transfer when there is a link to jump to other pages. , it will be more comfortable to use than localstorage.

But if the target used by a link is self, then sessionstorage cannot be found.

<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 other methods

Development tip: When we have the same variable name, we can set a string constant composed of uppercase letters.

 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 tool package

Encapsulates the storage method so that you can handle the events you want when using it.

Encapsulation file 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)

Use encapsulated code

   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-Creation of regular expressions

i means regardless of case, g means global, all, m means multi-line matching

  // 创建正则
    // 1> 匹配的规则pattern
    // 2> 匹配的修饰符flags
    const re1 = new RegExp("abc", "ig")
    const re2 = /abc/ig // 我是注释

RegExp - A walkthrough of regular expressions

 // 创建正则
    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-Usage of regular expressions

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-regular rules-character class

  // 创建正则
    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-regular rule-anchor

 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-regular rules-word boundaries

 // \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-regular rules-escaping

 // 定义正则: 对.转义
    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-regular rules-collection

  // 手机号的规则: 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-regular rules-quantifier

 // 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-regular rules-greedy and lazy

  // 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-regular rule-capturing group

 // 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-regular rule-or

  // 1.将捕获组作为整体
    const info = "dfabcabcfabcdfdabcabcabcljcbacballnbanba;jk;j"
    const abcRe = /(abc|cba|nba){2,}/ig
    console.log(info.match(abcRe))

RegExp-Regular Exercise-Lyrics Analysis

<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-regular exercise-time formatting

<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
}

Guess you like

Origin blog.csdn.net/weixin_56663198/article/details/131735989