JS-25 localStorage和sessionStorage;正则表达式概念+修饰符flag+使用方法+常用规则(字符类/锚点/转义字符串/集合/范围/量词/贪婪和惰性模式/捕获组)

本文主要是介绍JS-25 localStorage和sessionStorage;正则表达式概念+修饰符flag+使用方法+常用规则(字符类/锚点/转义字符串/集合/范围/量词/贪婪和惰性模式/捕获组),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 1_Storage
    • 1.1_认识Storage
    • 1.2_localStorage和sessionStorage的区别
    • 1.3_Storage常见的方法和属性
  • 2_正则表达式
    • 2.1_概念
    • 2.2_修饰符flag的使用
    • 2.3_正则表达式的使用方法
  • 3_正则表达式的常用规则
    • 3.1_字符类(Character classes)
    • 3.2_锚点(Anchors)
    • 3.3_转义字符串
    • 3.4_集合(Sets)和范围(Ranges)
    • 3.5_量词(Quantifiers)
    • 3.6_贪婪( Greedy)和惰性( lazy)模式
    • 3.7_捕获组(capturing group)
  • 4_案例
    • 4.1_歌词格式化
    • 4.2_时间格式化

1_Storage

1.1_认识Storage

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

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

在这里插入图片描述


1.2_localStorage和sessionStorage的区别

localStorage和sessionStorage看起来非常的相似。

它们的区别?

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

1.3_Storage常见的方法和属性

Storage.length:只读属性。 返回一个整数,表示存储在Storage对象中的数据项数量;

方法:

  • Storage.key(index):该方法接受一个数值n作为参数,返回存储中的第n个key名称;
  • Storage.getItem():该方法接受一个key作为参数,并且返回key对应的value;
  • Storage.setItem():该方法接受一个key和value,并且将会把key和value添加到存储中。 如果key存储,则更新其对应的值;
  • Storage.removeItem():该方法接受一个key作为参数,并把该key从存储中删除;
  • Storage.clear():该方法的作用是清空存储中的所有key;

2_正则表达式

2.1_概念

维基百科的解释:

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

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

在JavaScript中,正则表达式使用RegExp类来创建,也有对应的字面量的方式, 正则表达式主要由两部分组成:模式(patterns)和修饰符(flags)


2.2_修饰符flag的使用

常见修饰符

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

创建正则demo

    // 创建正则// 1> 前者。匹配的规则pattern// 2> 后置。匹配的修饰符flags// "abc"是可自己设置的字符串,"ig"表示修饰符,"i"是忽略大小写,"g"表示全部匹配// 写法一const re1 = new RegExp("abc", "ig")// 写法二const re2 = /abc/ig const message = "fdabc123 faBC323 dfABC222 A2324aaBc"// 需求: 将所有的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)

2.3_正则表达式的使用方法

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

方法描述
exec一个在字符串中执行查找匹配的 RegExp 方法,它返回一个数组(未匹配到则返回 null)。
test一个在字符串中测试是否匹配的 RegExp 方法,它返回 true 或 false。
match一个在字符串中执行查找匹配的 String 方法,匹配成功,它返回一个数组,且匹配到的内容放进数组;在未匹配到时会返回 null。
matchAll一个在字符串中执行查找所有匹配的 String 方法,它返回一个迭代器(iterator)。
search一个在字符串中测试匹配的 String 方法,它返回匹配到的位置索引,或者在失败时返回-1。
replace一个在字符串中执行查找匹配的 String 方法,并且使用替换字符串替换掉匹配到的子字符串。
split一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中
    // 创建正则const re1 = /abc/igconst message = "fdabc123 faBC323 dfABC222 A2324aaBc"// 使用正则对象上的实例方法// test方法: 检测某一个字符串是否符合正则的规则if (re1.test(message)) {console.log("message符合规则")  //message符合规则} else {console.log("message不符合规则")}// exec方法: 使用正则执行一个字符串const res1 = re1.exec(message)console.log(res1) //['abc', index: 2, input: 'fdabc123 faBC323 dfABC222 A2324aaBc', groups: undefined]// 表示"abc"在字符串变量message中存在于索引2的位置// 使用字符串的方法, 传入一个正则表达式// match方法:const result2 = message.match(re1)console.log(result2)  //(4) ['abc', 'aBC', 'ABC', 'aBc']// 在字符串变量message中,按照re1的正则规则,找到符合规则的内容,并汇总在数组中// matchAll方法// 注意: matchAll传入的正则修饰符必须加gconst 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) { //用foe of遍历返回的迭代器内容console.log(item)}//  replace/replaceAll方法  之前的代码已经演示过了// split方法   把符合正则表达式的地方,作为间隔,并存储到数组中// const result4 = message.split(re1)// console.log(result4)  //(5) ['fd', '123 f', '323 df', '222 A2324a', '']// search方法  const result5 = message.search(re1)console.log(result5)  //返回找到符合规则的第一个索引位置

3_正则表达式的常用规则

3.1_字符类(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 以外的任何字符,例如非拉丁字母或空格。

转换成大写字母,就可以把字符的规则反向


3.2_锚点(Anchors)

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

  • 符号 ^ 匹配文本开头;
  • 符号 $ 匹配文本末尾;
    const message = "My name is WHY."// 字符串方法   必须百分百匹配,不能忽略大小写if (message.startsWith("my")) {console.log("以my开头")}else{console.log("err: 以my开头") //err: 以my开头}if (message.endsWith("why")) {console.log("以why结尾")}else{console.log("err:以why结尾") //err:以why结尾}// 正则: 锚点  可以忽略大小写字母if (/^my/i.test(message)) {console.log("以my开头") //以why开头}if (/why\.$.test(message)) {console.log("以why结尾")  //以why结尾}const re = /^coder$/const info = "codaaaer"console.log(re.test(info)) // false

词边界(Word boundary)

  • 词边界 \b 是一种检查,就像 ^ 和 $ 一样,它会检查字符串中的位置是否是词边界。
  • 词边界测试 \b 检查位置的一侧是否匹配 \w,而另一侧则不匹配 “\w”
    const message = "My name! is WHY."// 需求: name, name必须是一个单独的词,不能是组合词// 词边界if (/\bname\b/i.test(message)) {console.log("有name, name有边界") //有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/igconsole.log(infos.match(timeRe))  //(2) ['11:56', '12:00']

3.3_转义字符串

特殊字符作为常规字符来使用,需对其进行转义, 只需在前面加个反斜杠\

常见的需要转义的字符: [ ] \ ^ $ . | ? \ * + ( )

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

练习:匹配所有以.js或者jsx结尾的文件名
在webpack当中,匹配文件名时就是以这样的方式。

    // 定义正则: 对.转义const re = /\./igconst message = "abc.hihi"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)// 问号?跟在正则表达式后面,具体表示匹配前面的一次或者0次,类似于{0,1},如:abc(d)?可匹配abc和abcd// 不加问号?的话,遍历只能找到第一个符合规则的,反之能找到多个符合规则的元素。const jsfileRe = /\.jsx?$/// 1.for循环做法const newFileNames = []for (const filename of fileNames) {if (jsfileRe.test(filename)) {newFileNames.push(filename)}}console.log(newFileNames) //['Home.jsx', 'index.js', 'util.js', 'format.js']// 2.filter高阶函数   函数作为参数输入。将符合条件的挑选出来,不符合条件的过滤掉。const newFileNames2 = fileNames.filter(filename => jsfileRe.test(filename))

3.4_集合(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_] 相同,它搜索一个字符,满足数字 0 到 9 或大写字母 A 到 F或小写字母a到z;
    // 手机号的规则: 1[3456789]033334444const phoneStarts = ["132", "130", "110", "120", "133", "155"]// 筛选出以1开头,然后第二位数字在3~9范围内的元素const phoneStartRe = /^1[3456789]\d/const filterPhone = phoneStarts.filter(phone => phoneStartRe.test(phone))console.log(filterPhone)  //(4) ['132', '130', '133', '155']const phoneNum = "133888855555"const phoneRe = /^1[3-9]\d{9}$/console.log(phoneRe.test(phoneNum)) //flase

3.5_量词(Quantifiers)

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

  • 因为它们的数量是不同的,所以需要给与数量一个范围;

  • 用来形容所需要的数量的词被称为量词( Quantifiers )。

数量 {n}

  • 确切的位数。比如要求5位数,就是{5}
  • 某个范围的位数。比如要求3~5位数,就是{3,5}

缩写:

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

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

    // 1.量词的使用const re = /a{3,5}/ig// 解释re规则:字母a要求连续3~5位,大小写字母都可以,全部匹配const message = "fdaaa2fdaaaaaasf42532fdaagjkljlaaaaf"const results = message.match(re)console.log(results)  //(3) ['aaa', 'aaaaa', 'aaaa']// 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) //(6) ['<div>', '<span>', '</span>', '<h2>', '</h2>', '</div>']

3.6_贪婪( Greedy)和惰性( lazy)模式

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

默认情况下的匹配规则是查找到匹配的内容后,会继续向后查找,一直找到最后一个匹配的内容, 这种匹配的方式,称之为贪婪模式(Greedy)。【理解为,一次吃很多】

懒惰模式中的量词。【理解,一次吃一点,吃多次】

  • 只要获取到对应的内容后,就不再继续向后匹配;【但是继续向后查找】
  • 在量词后面再加一个问号 ? 来启用它;
  • 所以匹配模式变为 *?+?,甚至将 ‘?’ 变为 ??
    // 1.贪婪模式/惰性模式const message = "我最喜欢的两本书: 《黄金时代》和《沉默的大多数》、《一只特立独行的猪》"// 默认.+采用贪婪模式const nameRe1 = /《.+》/ig//规则解释:第一个字符为《,中间字符(除了换行符)任意多个。最后一个字符为》const result1 = message.match(nameRe1)console.log(result1)  //(1) ['《黄金时代》和《沉默的大多数》、《一只特立独行的猪》']// 使用惰性模式const nameRe2 = /《.+?》/igconst result2 = message.match(nameRe2)console.log(result2)  //(3) ['《黄金时代》', '《沉默的大多数》', '《一只特立独行的猪》']

3.7_捕获组(capturing group)

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

捕获组有两个作用:

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

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

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

命名 捕获组

  • 用数字记录组很困难。
  • 对于更复杂的模式,计算括号很不方便。有一个更好的选择:给括号起个名字。
  • 这是通过在开始括号之后立即放置 ?<name> 来完成的。

非捕获组:

  • 有时需要括号才能正确应用量词,但不希望它们的内容出现在结果中。
  • 可以通过在开头添加 ?: 来排除组。【(?:) 只匹配,不捕获】
    // 1.捕获组const message = "我最喜欢的两本书: 《黄金时代》和《沉默的大多数》、《一只特立独行的猪》"// 使用惰性模式const nameRe = /(?:《)(?<why>.+?)(?:》)/ig// 解释规则:一对括号表示一个捕获组,而不是符号。//第一个捕获组:;一定要有《,但是在获取结果时,抛弃这个符号// 第二个捕获组:<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// 解释规则:字符串abc,必须连续两组以上console.log(info.match(abcRe))

在这里插入图片描述


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

  • 在正则表达式中,它用竖线 | 表示;
  • 通常会和捕获组一起来使用,在其中表示多个值
    const info = "dfabcabcfabcdfdabcabcabcljcbacballnbanba;jk;j"const abcRe = /(abc|cba|nba){2,}/ig//规则解释:abc或cba或nba,连续两个以上的console.log(info.match(abcRe))

4_案例

4.1_歌词格式化

    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})\]/iconst lyricInfos = []for (const lineString of lyricLineStrings) {// 1.获取时间const result = lineString.match(timeRe)if (!result) continueconst minuteTime = result[1] * 60 * 1000const secondTime = result[2] * 1000const mSecondTime = result[3].length === 3? result[3]*1: result[3]*10const time = minuteTime + secondTime + mSecondTime// 2.获取内容const content = lineString.replace(timeRe, "").trim()// 3.将对象放到数组中lyricInfos.push({ time, content })}console.log(lyricInfos)/*打印效果如下
0:{time: 0, content: '作词 : 许嵩'}
1: {time: 1000, content: '作曲 : 许嵩'}
2: {time: 2000, content: '编曲 : 许嵩'}
3: {time: 22240, content: '天空好想下雨'}
4: {time: 24380, content: '我好想住你隔壁'}
5: {time: 26810, content: '傻站在你家楼下'}*/


4.2_时间格式化

    // yyyy/MM/dd hh:mm:ss// yyyy*MM*dd hh-mm-ss// dayjs/momentfunction formatTime(timestamp, fmtString) {// 1.将时间戳转成Dateconst 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: 1099292301637}timeEl.textContent = formatTime(productJSON.endTime, "hh:mm:ss yyyy-MM-dd")    //14:58:21 2004-11-01

这篇关于JS-25 localStorage和sessionStorage;正则表达式概念+修饰符flag+使用方法+常用规则(字符类/锚点/转义字符串/集合/范围/量词/贪婪和惰性模式/捕获组)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/268628

相关文章

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

IDEA编译报错“java: 常量字符串过长”的原因及解决方法

《IDEA编译报错“java:常量字符串过长”的原因及解决方法》今天在开发过程中,由于尝试将一个文件的Base64字符串设置为常量,结果导致IDEA编译的时候出现了如下报错java:常量字符串过长,... 目录一、问题描述二、问题原因2.1 理论角度2.2 源码角度三、解决方案解决方案①:StringBui

C#中读取XML文件的四种常用方法

《C#中读取XML文件的四种常用方法》Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具,下面我们就来看看C#中读取XML文件的方法都有哪些吧... 目录XML简介格式C#读取XML文件方法使用XmlDocument使用XmlTextReader/XmlTextWr

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

JS 实现复制到剪贴板的几种方式小结

《JS实现复制到剪贴板的几种方式小结》本文主要介绍了JS实现复制到剪贴板的几种方式小结,包括ClipboardAPI和document.execCommand这两种方法,具有一定的参考价值,感兴趣的... 目录一、Clipboard API相关属性方法二、document.execCommand优点:缺点:

CSS弹性布局常用设置方式

《CSS弹性布局常用设置方式》文章总结了CSS布局与样式的常用属性和技巧,包括视口单位、弹性盒子布局、浮动元素、背景和边框样式、文本和阴影效果、溢出隐藏、定位以及背景渐变等,通过这些技巧,可以实现复杂... 一、单位元素vm 1vm 为视口的1%vh 视口高的1%vmin 参照长边vmax 参照长边re

Java实现状态模式的示例代码

《Java实现状态模式的示例代码》状态模式是一种行为型设计模式,允许对象根据其内部状态改变行为,本文主要介绍了Java实现状态模式的示例代码,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来... 目录一、简介1、定义2、状态模式的结构二、Java实现案例1、电灯开关状态案例2、番茄工作法状态案例

C#比较两个List集合内容是否相同的几种方法

《C#比较两个List集合内容是否相同的几种方法》本文详细介绍了在C#中比较两个List集合内容是否相同的方法,包括非自定义类和自定义类的元素比较,对于非自定义类,可以使用SequenceEqual、... 目录 一、非自定义类的元素比较1. 使用 SequenceEqual 方法(顺序和内容都相等)2.

关于Gateway路由匹配规则解读

《关于Gateway路由匹配规则解读》本文详细介绍了SpringCloudGateway的路由匹配规则,包括基本概念、常用属性、实际应用以及注意事项,路由匹配规则决定了请求如何被转发到目标服务,是Ga... 目录Gateway路由匹配规则一、基本概念二、常用属性三、实际应用四、注意事项总结Gateway路由

Python中操作Redis的常用方法小结

《Python中操作Redis的常用方法小结》这篇文章主要为大家详细介绍了Python中操作Redis的常用方法,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解一下... 目录安装Redis开启、关闭Redisredis数据结构redis-cli操作安装redis-py数据库连接和释放增