storage和正则表达式

一、Storage

1.认识Storage

WebStorage主要提供了一种机制,可以让浏览器提供一种比cookie更直观的key、value存储方式:

  • localStorage:本地存储,提供的是一种永久性的存储方法,在关闭掉网页重新打开时,存储的内容依然保留;
  • sessionStorage:会话存储,提供的是本次会话的存储,在关闭掉会话时,存储的内容会被清除;
localStorage.setItem("name", "local");
sessionStorage.setItem("name", "session");

2.localStorage和sessionStorage的区别

我们会发现localStorage和sessionStorage看起来非常的相似。

那么它们有什么区别呢?

  • 验证一:关闭网页后重新打开,localStorage会保留,而sessionStorage会被删除;
  • 验证二:在页面内实现跳转,localStorage会保留,sessionStorage也会保留;
  • 验证三:在页面外实现跳转(打开新的网页),localStorage会保留,sessionStorage不会被保留;

3.Storage常见的方法和属性

Storage有如下的属性和方法:

属性

Storage.length:只读属性

  • 返回一个整数,表示存储在Storage对象中的数据项数量;

方法

Storage.key():该方法接受一个数值n作为参数,返回存储中的第n个key名称;

Storage.getItem():该方法接受一个key作为参数,并且返回key对应的value;

Storage.setItem():该方法接受一个key和value,并且将会把key和value添加到存储中。

  • 如果key存储,则更新其对应的值;

Storage.removeItem():该方法接受一个key作为参数,并把该key从存储中删除;

Storage.clear():该方法的作用是清空存储中的所有key;

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()

4.Storage工具封装

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)
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  <script src="./js/cache.js"></script>
  <script>

    localCache.setCache("sno", 111)

    // storage本身是不能直接存储对象类型的
    const userInfo = {
      name: "abc",
      nickname: "def",
      level: 100,
      imgURL: "http://github.com/abc.png"
    }

    // localStorage.setItem("userInfo", JSON.stringify(userInfo))
    // console.log(JSON.parse(localStorage.getItem("userInfo")))

    sessionCache.setCache("userInfo", userInfo)
    console.log(sessionCache.getCache("userInfo"))

  </script>

</body>
</html>

二、正则表达式

1.什么是正则表达式?

我们先来看一下维基百科对正则表达式的解释:

  • 正则表达式(英语:Regular Expression,常简写为regex、regexp或RE),又称正则表示式、正则表示法、规则表达式、常规表示法,是计算机科学的一个概念;
  • 正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
  • 许多程序设计语言都支持利用正则表达式进行字符串操作。

简单概况:正则表达式是一种字符串匹配利器,可以帮助我们搜索、获取、替代字符串;

在JavaScript中,正则表达式使用RegExp类来创建,也有对应的字面量的方式:

  • 正则表达式主要由两部分组成:模式(patterns)和修饰符(flags)
const re1 = new RegExp("hello", "i")
const re2 = /hello/i

2.正则表达式的使用方法

有了正则表达式我们要如何使用它呢?

  • JavaScript中的正则表达式被用于 RegExp 的 exec 和 test 方法;
  • 也包括 String 的 match、matchAll、replace、search 和 split 方法;

在这里插入图片描述

// 创建正则
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 =  "输入的内容不符合规则要求, 请重新输入"
//   }
// }

3.修饰符flag的使用

常见的修饰符

flag含义
g全部的,给我匹配全部的
i忽略大小写
m多行匹配

需求:

  • 获取一个字符串中所有的abc
  • 将一个字符串中的所有abc换成大写
let message = "Hello abc, abc, Abc, AAaBc"
const pattern = /abc/ig
const results = message.match(pattern)
console.log(results)

message = message.replaceAll(pattern, "ABC")
console.log(message)

4.规则 – 字符类(Character classes)

字符类(Character classes) 是一个特殊的符号,匹配特定集中的任何符号。

字符含义
\d(“d” 来自 “digit”)数字:从 0 到 9 的字符。
\s(“s” 来自 “space”)空格符号:包括空格,制表符 \t,换行符 \n 和其他少数稀有字符,例如 \v,\f 和 \r。
\w(“w” 来自 “word”)“单字”字符:拉丁字母或数字或下划线 _。
.(点)点 . 是一种特殊字符类,它与 “除换行符之外的任何字符” 匹配

反向类(Inverse classes)

  • \D 非数字:除 \d 以外的任何字符,例如字母。
  • \S 非空格符号:除 \s 以外的任何字符,例如字母。
  • \W 非单字字符:除 \w 以外的任何字符,例如非拉丁字母或空格。
const message = "CSS2.5"
const pattern = /CSS\d(\.\d)?/i
console.log(message.match(pattern))

5.规则 – 锚点(Anchors)

符号 ^ 和符号 $ 在正则表达式中具有特殊的意义,它们被称为“锚点”。

  • 符号 ^ 匹配文本开头
  • 符号 $ 匹配文本末尾
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

词边界(Word boundary)

  • 词边界 \b 是一种检查,就像 ^ 和 $ 一样,它会检查字符串中的位置是否是词边界
  • 词边界测试 \b 检查位置的一侧是否匹配 \w,而另一侧则不匹配 “\w”

匹配下面字符串中的时间:

const message = "now time 22:45, number is 123.456"
const timepattern = /\b\d\d:\d\d\b/g
console.log(message.match(timepattern))

6.规则 – 转义字符串

如果要把特殊字符作为常规字符来使用,需要对其进行转义

  • 只需要在它前面加个反斜杠

常见的需要转义的字符:

[] \ ^ $ . | ? * + ()

  • 斜杠符号 / 并不是一个特殊符号,但是在字面量正则表达式中也需要转义;

练习:匹配所有以.js或者jsx结尾的文件名

const filenames = ["abc.js", "cba.java", "nba.html"]
const newNames = filenames.filter(item => {
    return /\.jsx?$/.test(item)
})

在webpack当中,匹配文件名时就是以这样的方式。

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

7.集合(Sets)和范围(Ranges)

有时候我们只要选择多个匹配字符的其中之一就可以:

  • 在方括号 […] 中的几个字符或者字符类意味着“搜索给定的字符中的任意一个”;

集合(Sets)

  • 比如说,[eao] 意味着查找在 3 个字符 ‘a’、‘e’ 或者 ‘o’ 中的任意一个`;

范围(Ranges)

  • 方括号也可以包含字符范围;
  • 比如说,[a-z] 会匹配从 a 到 z 范围内的字母,[0-5] 表示从 0 到 5 的数字;
  • [0-9A-F] 表示两个范围:它搜索一个字符,满足数字 0 到 9 或字母 A 到 F;
  • \d —— 和 [0-9] 相同;
  • \w —— 和 [a-zA-Z0-9_] 相同;

案例:匹配手机号码

const phonePattern = /^1[356789]\d{9}$/

排除范围:除了普通的范围匹配,还有类似 [^…] 的“排除”范围匹配;

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

8.量词(Quantifiers)

假设我们有一个字符串 +7(903)-123-45-67,并且想要找到它包含的所有数字。

  • 因为它们的数量是不同的,所以我们需要给与数量一个范围;
  • 用来形容我们所需要的数量的词被称为量词( Quantifiers )。

数量 {n}

  • 确切的位数:{5}
  • 某个范围的位数:{3,5}

缩写:

  • +:代表一个或多个,相当于 {1,}
  • ?:代表零个或一个,相当于 {0,1}。换句话说,它使得符号变得可选;
  • *:代表着零个或多个,相当于 {0,}。也就是说,这个字符可以多次出现或不出现;

案例:匹配开始或结束标签

// 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)

9.贪婪( Greedy)和惰性( lazy)模式

如果我们有这样一个需求:匹配下面字符串中所有使用《》包裹的内容

const message = "我最喜欢的两本书:《黄金时代》和《沉默的大多数》"
const results = message.match(/《.+》/g)
console.log(results)

默认情况下的匹配规则是查找到匹配的内容后,会继续向后查找,一直找到最后一个匹配的内容

  • 这种匹配的方式,我们称之为贪婪模式(Greedy)

懒惰模式中的量词与贪婪模式中的是相反的。

  • 只要获取到对应的内容后,就不再继续向后匹配
  • 我们可以在量词后面再加一个问号 ? 来启用它;
  • 所以匹配模式变为 *? 或 +?,甚至将 ‘?’ 变为 ??
const message = "我最喜欢的两本书:《黄金时代》和《沉默的大多数》"
const results = message.match(/《.+?》/g)
console.log(results)

10.捕获组(capturing group)

模式的一部分可以用括号括起来 (…),这称为“捕获组(capturing group)”。

这有两个作用:

  • 它允许将匹配的一部分作为结果数组中的单独项
  • 它将括号视为一个整体;

方法 str.match(regexp),如果 regexp 没有 g 标志,将查找第一个匹配并将它作为一个数组返回:

  • 在索引 0 处:完全匹配。
  • 在索引 1 处:第一个括号的内容。
  • 在索引 2 处:第二个括号的内容。
  • …等等…

案例:匹配到HTML标签,并且获取其中的内容

const str = "<h1>title</h1>"
const result = str.match(/<(.+?)>/)
console.log(result[0])
console.log(result[1])

命名组:

  • 用数字记录组很困难。
  • 对于更复杂的模式,计算括号很不方便。我们有一个更好的选择:给括号起个名字。
  • 这是通过在开始括号之后立即放置 ? 来完成的。
const result = message.match(/(?<codermq>hel)lo/i)

非捕获组:

  • 有时我们需要括号才能正确应用量词,但我们不希望它们的内容出现在结果中。
  • 可以通过在开头添加 ?: 来排除组。
const result = message.match(/(?<codermq>hel)(lo)/)

or是正则表达式中的一个术语,实际上是一个简单的“或”。

  • 在正则表达式中,它用竖线 | 表示;
  • 通常会和捕获组一起来使用,在其中表示多个值;
// 1.将捕获组作为整体
const info = "dfabcabcfabcdfdabcabcabcljcbacballnbanba;jk;j"
const abcRe = /(abc|cba|nba){2,}/ig
console.log(info.match(abcRe))

11.封装日期格式化函数

function formatDate(timestamp, formatString) {
    const date = new Date(timestamp);
    const obj = {
        "y+": date.getFullYear(),
        "M+": date.getMonth() + 1,
        "d+": date.getDate(),
        "h+": date.getHours(),
        "m+": date.getMinutes(),
        "s+": date.getSeconds(),
        "S+": date.getMilliseconds()
    };

    for (const key in obj) {
        if (new RegExp(`(${key})`).test(formatString)) {
            const value = (obj[key] + "").padStart(2, "0");
            formatString = formatString.replaceAll(RegExp.$1, value);
        }
    }
    return formatString;
}
const nowDate = Date.now();
const formatStr = formatDate(nowDate, "yyyy-MM-dd hh:mm:ss.SSS");
console.log(formatStr);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/157281.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Figma快速指南:3点核心技巧助你迅速掌握!

Figma确立了在线设计工具的形式&#xff0c;在国际上具有不可低估的影响力。Figma颠覆了传统的设计模式&#xff0c;不仅是为了设计师&#xff0c;也是为了设计本身。从产品经理到研究人员&#xff0c;从开发人员到营销人员&#xff0c;设计过程需要很多团队角色的参与&#xf…

鸿蒙/Android上最大的毒瘤:快应用服务

鸿蒙/Android上最大的毒瘤&#xff1a;快应用服务 2023.3.22版权声明&#xff1a;本文为博主chszs的原创文章&#xff0c;未经博主允许不得转载。 1、什么是快应用&#xff1f; “快应用” 是安卓厂&#xff08;华&#xff0c;米&#xff0c;O、V、魅族、努、联、加&#xf…

精密云工程:智能激活业务速率 ——华为云11.11联合大促倒计时 仅剩3日

现新客3.96元起&#xff0c;下单有机会抽HUAWEI P60 Art&#xff0c;福利仅限双十一&#xff0c;机会唾手可得&#xff0c;立即行动&#xff01; 双十一购物节来临倒计时&#xff0c;华为云备上多款增值产品&#xff0c;以最优品质迸发冬日技术热浪&#xff0c;满足行业技术应用…

vue 表单重置功能

1、标签加上ref属性&#xff0c;名称自定义 <el-form ref"searchForm"></el-form>2、表单项标签添加prop属性&#xff0c;prop属性需要与input框绑定v-model的属性一致 <el-form-item label"名称" prop"name"><el-input …

SpringSecurity6 | 自动配置(上)

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; Java从入门到精通 ✨特色专栏&#xf…

Android 实现三维空间坐标系(WebView与JS交互,支持多条曲线,可设置坐标轴翻转等)

全部代码已经上传,点击上方进行下载 支持多条曲线的绘制,可旋转拖动放大缩小 1.布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app=&quo…

【Linux】第十七站:进程创建与进程终止

文章目录 一、进程创建1.fork函数2.写时拷贝3.批量化创建多个进程 二、进程终止1.进程退出场景2.进程退出的方法&#xff08;1&#xff09;exit和return&#xff08;2&#xff09;_exit和exit 一、进程创建 1.fork函数 在linux中fork函数时非常重要的函数&#xff0c;它从已存…

Java 中的全部锁

目录 一. 前言 二. 乐观锁 VS 悲观锁 三. 自旋锁 VS 适应性自旋锁 四. 无锁 VS 偏向锁 VS 轻量级锁 VS 重量级锁 五. 公平锁 VS 非公平锁 六. 可重入锁 VS 非可重入锁 七. 独享锁&#xff08;排他锁&#xff09; VS 共享锁 八. 总结 一. 前言 Java提供了种类丰富的锁&a…

中小型企业内网搭建

某中小型公司客户提出网络比较单一整体都在一个大的广播域中&#xff0c;AP无线的SSID有很多个&#xff0c;包括一些小的无线路由器散发出来的信号&#xff0c;用起来网络不太稳定&#xff0c;并且AP的SSID要分开&#xff0c;办公室只有单个SSID&#xff0c;不允许出现其他的&a…

vue3+vite+ts 发布自定义组件到npm

vue3vite 发布自定义组件到npm 初始化项目编写组件配置打包组件上传到npm测试组件库 初始化项目 // 创建项目 pnpm create vite vue-test-app --template vue-ts// 运行项目 cd vite vue-test-app pnpm install pnpm run dev编写组件 1、根目录下创建packages目录作为组件的开…

leetcode刷题日志-151反转字符串中的单词

给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 注意&#xff1a;输入字符串 s中可能会存在前导空格、尾随…

面向对象成员之属性

属性:通过方法改造出来 # 1.编写时 # 方法上方写property # 方法参数:只有一个self # 2.使用时:无需加括号 对象.方法 # 3.应用场景:对于简单的方法,当无需传参且有返回值时,可以使用 property class Foo(object):def _init_(self):...propertydef start(self):return 1pr…

【vitis】 AIE basic

AIE vs AIE-ML versal 期间分类 文件 操作 vitis -new -w . 安装

易点易动固定资产管理系统场景应用一:集成ERP/财务系统

在企业的日常运营中&#xff0c;固定资产管理是一个重要而繁琐的任务。传统的手工管理方式往往效率低下且容易出错&#xff0c;给企业带来不必要的成本和风险。为了解决这一问题&#xff0c;易点易动固定资产管理系统应运而生。本文将重点介绍易点易动固定资产管理系统在集成ER…

【C语法学习】26 - strcat()函数

文章目录 1 函数原型2 参数3 返回值4 使用说明5 示例5.1 示例1 1 函数原型 strcat()&#xff1a;将src指向的字符串拼接在dest指向的字符串末尾&#xff0c;函数原型如下&#xff1a; char *strcat(char *dest, const char *src);2 参数 strcat()函数有两个参数src和dest&am…

SAP BAPI BAPI_CLASS_EXISTENCECHECK

物料分类是否存在的BAPI

Molecular Plant | ChIP-seq+RNA-seq解析E2F转录因子在植物复制胁迫响应中的独特和互补作用

生物体的生存完全依赖于它们对基因组完整性的维持&#xff0c;而基因组完整性受到增殖细胞复制胁迫的永久威胁。尽管植物DNA损伤反应&#xff08;DDR&#xff09;调节因子SOG1已被证明能够应对复制缺陷&#xff0c;但越来越多的证据表明&#xff0c;还有其他途径独立于SOG1发挥…

【IDEA 使用easyAPI、easyYapi、Apifox helper等插件时,导出接口文档缺少代码字段注释的相关内容、校验规则的解决方法】

问题 IDEA 使用easyAPI、easyYapi、Apifox helper等插件时&#xff0c;导出的接口文档上面&#xff0c;缺少我们代码里的注解字段&#xff0c;如我们规定了NOTNULL、字段描述等。 问题链接&#xff0c;几个月之前碰到过&#xff0c;并提问了&#xff0c;到现在解决&#xff0c…

k8s ingress高级用法一

前面的文章中&#xff0c;我们讲述了ingress的基础应用&#xff0c;接下来继续讲解ingress的一些高级用法 一、ingress限流 在实际的生产环境中&#xff0c;有时间我们需要对服务进行限流&#xff0c;避免单位时间内访问次数过多&#xff0c;常用的一些限流的参数如下&#x…

【Android】如何使用模拟器调试安卓项目

1、电脑安装逍遥模拟器&#xff0c;用来跑安卓项目。安装好模拟器之后&#xff0c;直接起安卓项目&#xff0c;自动会在选择设备处显示 2、如果前端是安卓后端是其他语言的话&#xff0c;这种前后端分离的模式&#xff0c;需要监听端口&#xff0c;原因是运行安卓和后端编译器都…