7天精通Web APIs——正则阶段案例(理论+实战)(第六天)

news2024/10/6 14:25:10

正则表达式的定义和使用

定义:是一种匹配模式,用于匹配字符串中字符组合
作用:表单验证(匹配)、过滤敏感词(替换)、字符串中提取我们想要的部分(提取)
使用分为两步:
1.定义正则表达式
2.检测查找是否匹配

语法:

案例:
注意 查找方法有两种 重点test()

 <script>
        let str = '哈哈嘻嘻可可爱爱'
        // 1.定义正则表达式
        const aa = /嘻嘻/
        // 2.推荐:使用test方法查找  结果返回的是布尔值  返回true或者false
        console.log(aa.test(str))
        // 3.使用exec方法查找  结果返回的是数组  有结果返回数组 没有结果返回null
        console.log(aa.exec(str));
    </script>

元字符(特殊字符)

以下通过一个例子理解元字符和普通字符的区别
在匹配时,如果是匹配的为英文字符。abcdefghijklmn…z,此时使用普通字符就很麻烦,要写abcdefghijklmn…z,可以直接用元字符来替代 即:[a-z]

边界符

^ 以xxxx开头
$ 以xxxx结尾
属于精确匹配

 <script>
        // 正则表达式直接使用的方法:
        console.log(//.test('哈'))
        console.log(//.test('哈哈'))
        console.log(//.test('二哈'))
        // 边界符
        console.log(/哈$/.test('哈'))
        console.log(/^哈$/.test('哈'))
        console.log(/哈$/.test('二哈'))
          最需要注意的  精确匹配  所以是false   读作:以哈开头,以哈结尾  这个哈是同一个哈
        console.log(/^哈$/.test('二哈'));
    </script>

量词

在这里插入图片描述

注意:把这里的重复理解为出现即可!

 <script>
        console.log('**********************')
        // *  只能有哈 出现0次或者更多次
        console.log(/^哈*$/.test('')) // 需要注意true
        console.log(/^哈*$/.test('哈')) //true
        console.log(/^哈*$/.test('哈哈哈')) //true
        console.log(/^哈*$/.test('二哈')) //false
        console.log(/^哈*$/.test('二哈很傻')) //false
        console.log(/^哈*$/.test('哈很啥')) //false
        // 以ha开头 并且重复哈多个 在以哈结尾  所以只能有哈
        console.log(/^哈*$/.test('哈很哈')) //flase
        console.log('++++++++++++++++++++++++++++')
        // +    出现1次或者多次
        console.log(/^哈+$/.test('')) // 注意:false
        console.log(/^哈+$/.test('哈')) //true
        console.log(/^哈+$/.test('哈哈哈')) //true
        console.log(/^哈+$/.test('二哈')) //false
        console.log(/^哈+$/.test('二哈很傻')) //false
        console.log(/^哈+$/.test('哈很啥')) //false
        console.log(/^哈+$/.test('哈很哈')) //flase
        console.log('???????????????????????????')
        // ? 出现0次或者1次
        console.log(/^哈?$/.test('')) //true
        console.log(/^哈?$/.test('哈')) //true
        console.log(/^哈?$/.test('哈哈')) //false
        console.log(/^哈?$/.test('二哈')) //false
        console.log(/^哈?$/.test('二哈很傻')) //false
        console.log(/^哈?$/.test('哈很啥')) //false
        console.log(/^哈?$/.test('哈很哈')) //flase
        console.log('{n}{n}{n}{n}{n}{n}{n}{n}{n}{n}{n}{n}{n}{n}{n}{n}{n}{n}{n}{n}')
        //{n}  出现n次
        console.log(/^哈{4}$/.test(''))
        console.log(/^哈{4}$/.test('哈'))
        console.log(/^哈{4}$/.test('哈哈'))
        console.log(/^哈{4}$/.test('哈哈哈'))
        console.log(/^哈{4}$/.test('哈哈哈哈')) //true 其余为false
        console.log('{n,}{n,}{n,}{n,}{n,}{n,}{n,}{n,}{n,}{n,}{n,}{n,}{n,}{n,}{n,}{n,}')
        //{n,} 出现n次或者更多次同理
        //{n,m} 出现n到m次
    </script>

案例:表单验证 填写验证码,当表单失去焦点就开始验证,如果符合正则规则就在span中添加right类,否则添加error类。

注意:使用classList,后面的样式会覆盖前面的样式;而使用className,重复的类名实现覆盖 进而达到样式切换自如

<style>
        span {
            display: inline-block;
            width: 250px;
            height: 30px;
            vertical-align: middle;
            line-height: 30px;
            padding-left: 15px;
        }
        .error {
            color: red;
            background: url(./images/error1.png) no-repeat left center;
        }
        .right {
            color: green;
            background: url(./images/right.png) no-repeat left center;
        }
    </style>
 <input type="text">
    <span></span>
    <script>
        const reg = /^[a-zA-Z0-9-_]{6,16}$/
        const input = document.querySelector('input')
        const span = input.nextElementSibling
        input.addEventListener('blur', function () {
            if (reg.test(this.value)) {
                span.innerHTML = '输入正确'
                span.className = 'right'
               // 根据样式顺序 后面的样式会覆盖前面的,因此使用获取类名
                // span.classList.add('right')
            } else {
                span.innerHTML = '请输入6~16位的英文数字下划线'
                span.className = 'error'
                // span.classList.add('error')
            }
        })
    </script>

复杂的正则细解

/^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8 \d |9[0-35-9])\d{8}$ /
^$表示以什么开头 以什么结尾
1 占了一位
\d 表示0-9任意一个数字
(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9]) 小括号中 有或 表示3之后任意一个数字或者 4 之后5-9任意一个数字 或者 5 之后0-3,5-9任意一个数字 或者6 之后567之间任一个数字 7 之后0-8任一个数字 或者8 之后0-9任意一个数字 或者 9 之后0-3,5-9之间任一个数字 也就是这里占两位
\d{8} 从0-9之间8位任意数字

字符类

1)为什么叫字符类,是因为[]中有个 - 连字符
使用连字符 - 表示一个范围
[a-z] 表示 a 到 z 26个英文字母都可
[a-zA-Z] 大小写都可以
[0-9] 表示 0~9 的数字都可

也就是说:[] n选1 或者多个 主要是看有没有"“^$”",如果有的话,就是n选1;没有则是n选m(或n)

 //字符类 n选一
        console.log(/[abc]/.test('a')) //true
        console.log(/[abc]/.test('abc')) //true
        console.log(/^[abc]$/.test('a')) //true
        console.log(/^[abc]$/.test('b')) //true
        console.log(/^[abc]$/.test('ab'))  //加了开头结尾  只能有一个  false
        console.log(/^[abc]{2}$/.test('ab'))  //true  出现2个
        //字符类[a-z] 只选一个
        console.log(/^[a-z]$/.test('p'))
        console.log(/^[A-Z]$/.test('p'))  //区分大小写
        // 字符类结合量词
        console.log(/^[0-9a-zA-Z]$/.test('p'))
        console.log(/^[0-9][0-9]{4,}$/.test(10000))//true
  1. 取反字符

[^a-z] 表示除了小写英文字母之外的一个字符

  //表示除了小子字母其他都为true  在正则表达式中的称为开头  中括号中的为取反符号
  console.log(/[^a-z]/.test('A'))//true 

修饰符+过滤敏感词

修饰符附加在正则表达式之后
i 是单词 ignore 的缩写,匹配时字母不区分大小写
g 是单词 global 的缩写,顾名思义,是全局的意思,全局搜索满足正则表达式的结果
案例:

<script>
        console.log(/^java$/i.test('JAVA'))  //true
        const str = 'java棒,JAVA好'
        // 在全局搜索 并且忽略大小写 并且把字母更换为其他文字(全局更换)
        // const re = str.replace(/java/ig, '前端')
        const re = str.replace(/java|JAVA/g, '前端')
        console.log(re);
    </script>

这里有个好奇的地方,不知道大家好奇不 就是我发现,下面代码中tx.value不是字符串吗,怎么可以调用replace方法呢,后来我查到资料,说:js的字符串可以通过一些内置的包装对象来访问其方法和属性。也就是:当我们尝试使用字符串的时候,JavaScript引擎会自动将原始字符串值临时转换为一个对应的包装对象(在这种情况下是 String 对象),然后在这个包装对象上调用方法。方法执行完成后,结果会被返回,而包装对象本身则会被丢弃。这个过程被称为装箱或自动包装。

  <textarea name="" id="" cols="30" rows="10"></textarea>
    <button>发布</button>
    <div></div>
    <script>
        const tx = document.querySelector('textarea')
        const btn = document.querySelector('button')
        const div = document.querySelector('div')
        btn.addEventListener('click', function () {
            // 死记硬背
            // console.log(tx.value)
            // replace前面是一句话
            div.innerHTML = tx.value.replace(/激情|基情/g, '**')
            console.log(typeof tx.value)
        })
    </script>

综合案例

完整页面资源大家可以直接下载
注册页面主要分为
①发送验证码模块
②各个表单验证模块
③勾选已经同意模块
④下一步验证全部模块,只要有一个input验证不通过就不同意提交
第一部分我们需要将页面设计成当时间达到的时候,因为是短信验证码,所以我们换成重新获取;又因为短信验证码的内容是需要与后台交互的 所以这里先不做
这里给的页面内容很多,听老师说直接我们对哪个表单设计,直接通过检查找到即可,但我还是怕看不懂,还将注册页面的css和html仔细分析了一下,因为怕后面整js的时候出现卡顿的情况,不过后来在整完css和html后,重新整js,发现不用弄我的那一套操作,大家可以按照老师说的!需要对哪一个表单设计就检查一下,找到对应的表单!
注册页面模块:
发送短信验证模块:

   // 发送短信验证模块
        // 1.获取元素  对谁设计就获取谁
        const code = document.querySelector('.code')
        let flag = true  //节流阀 也就是时间不到就不能点
        code.addEventListener('click', function () {
            // 2.想到获取元素之后,是为了让他变成其他文字
            if (flag) {
                flag = false
                let i = 5
                this.innerHTML = `0${i}秒后重新获取`
                let timerId = setInterval(function () {
                    i--
                    // 注意这里不能使用this  只有在函数直接子元素中才可以用  上句代码this就可以
                    code.innerHTML = `0${i}秒后重新获取`
        // 这里注意一定要将if判断语句写在里面  写在定时器外面的话  定时器就会一直减减,根本不会到下面去执行
                    if (i === 0) {
                        clearInterval(timerId)
                        code.innerHTML = '重新获取'
                        flag = true
                    }
                }, 1000)
            }
        })

各个表单验证模块:
用户名称的验证思路是:先获取元素,然后将元素中的值与正则表达式进行匹配,如果不符合规范在下面就会有红色提示!
先准备好正则表达式匹配规则

  // 各个表单验证模块
        // 用户名验证模块
        const username = document.querySelector('[name="username"]')
        // 这里需要多次渲染到页面 所以单独写了个函数
        // 不好理解就死记硬背:因为这样的表单有很多,都是判断值对不对,不对就需要显示红色提示,红色提示需要渲染到页面,所以就用一个函数包装,这样方便其他函数一改名字就可以使用
        username.addEventListener('change', verifyName)
        function verifyName () {
            const span = username.nextElementSibling
            const reg = /^[a-zA-Z0-9-_]{6,10}$/
            if (!reg.test(username.value)) {
                span.innerText = '输入不合法,请输入6-10位'
                return false
            }
            span.innerText = ""
            return true
        }

        // 手机号验证
        const phone = document.querySelector('[name=phone]')
        phone.addEventListener('change', verifyPhone)
        function verifyPhone () {
            const span = phone.nextElementSibling
            const reg = /^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/
            if (!reg.test(phone.value)) {
                span.innerText = '输入不合法,请输入正确的11位手机号码'
                return fasle
            }
            span.innerText = ""
            return true
        }
        // 验证码
        const codeInput = document.querySelector('[name="code"]')
        codeInput.addEventListener('change', verifyCode)
        function verifyCode () {
            const span = codeInput.nextElementSibling
            const reg = /^\d{6}$/
            if (!reg.test(codeInput.value)) {
                span.innerText = '输入不合法,6位数字'
                return false
            }
            span.innerHTML = ""
            return true
        }
        // 密码框
        const pwd = document.querySelector('[name="password"]')
        pwd.addEventListener('change', verifyPwd)
        function verifyPwd () {
            const span = pwd.nextElementSibling
            const reg = /^[a-zA-Z0-9-_]{6,20}$/
            if (!reg.test(pwd.value)) {
                span.innerHTML = '输入不合法,6-20位数字字母符号组成'
                return false
            }
            span.innerHTML = ""
            return true
        }

密码的再次验证 只要与之前密码框输入的值不同 就报红

 // 密码的再次验证
        const confirm = document.querySelector('[name="confirm"]')
        confirm.addEventListener('change', verigyConfirm)
        function verigyConfirm () {
            const span = confirm.nextElementSibling
            if (confirm.value !== pwd.value) {
                span.innerHTML = '两次密码输入不一致'
                return false
            }
            span.innerText = ""
            return true
        }

判断表单是否填写成功

 const queren = document.querySelector('.icon-queren')
        queren.addEventListener('click', function () {
            this.classList.toggle('icon-queren2')
        })
        const form = document.querySelector('form')
        form.addEventListener('submit', function (e) {
            if (!queren.classList.contains('icon-queren2')) {
                alert('请勾选同意协议')
                e.preventDefault()
            }
            // 这就是true和false的作用 为后来表单是否正确填写做验证
            if (!verifyName()) e.preventDefault()
            if (!verifyPhone()) e.preventDefault()
            if (!verifyCode()) e.preventDefault()
            if (!verifyPwd()) e.preventDefault()
            if (!verifyConfirm()) e.preventDefault()
        })

登录模块 有一个tab栏切换 选定指定的标签页来显示或者隐藏下面的页面

 <script>
    // tab栏切换 事件委托
    const tab_nav = document.querySelector('.tab-nav')
    const pane = document.querySelectorAll('.tab-pane')
    tab_nav.addEventListener('click', function (e) {
      if (e.target.tagName === 'A') {
        // 取消上一个active  给当前元素添加active类
        tab_nav.querySelector('.active').classList.remove('active')
        e.target.classList.add('active')
        // 先干掉所有人 for循环
        for (let i = 0; i < pane.length; i++) {
          pane[i].style.display = 'none'
        }
        // 让对应的序号的大pane显示
        pane[e.target.dataset.id].style.display = 'block'
      }
    })
    //点击提交模块
    const form = document.querySelector('form')
    const agree = document.querySelector('[name=agree]')
    const username = document.querySelector('[name=username]')
    form.addEventListener('submit', function (e) {
      e.preventDefault()
      if (!agree.checked) {
        return alert('请勾选同意协议')
      }
      // 记录用户名到本地存储
      localStorage.setItem('xtx-uname', username.value)
      // 跳转到首页
      location.href = './index.html'
    })
  </script>

用户登录或者未登录状态的切换

 <script>
    const li1 = document.querySelector('.xtx_navs li:first-child')
    const li2 = li1.nextElementSibling
    function render () {
      const uname = localStorage.getItem('xtx-uname')
      if (uname) {
        li1.innerHTML = `<a href="javascript:;"><i class="iconfont icon-user">${uname}</i></a>`
        li2.innerHTML = '<a href="javascript:;">退出登录</a>'
      } else {
        li1.innerHTML = '<a href="./login.html">请先登录</a>'
        li2.innerHTML = '<a href="./register.html">免费注册</a>'
      }
    }
    render()
  </script>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL-InnoDB数据存储结构

1、存储结构-页 索引结构提供了高效的索引方式&#xff0c;索引信息以及数据记录都保存在数据文件或索引文件中&#xff08;本质存储在页结构中&#xff09; 1.1、磁盘与内存交互的基本单位&#xff1a;页 在InnoDB中将数据划分为若干页&#xff0c;页的默认大小为&#xff…

SQLZOO:The JOIN operation

数据表&#xff1a;game-gaol-eteam game idmdatestadiumteam1team210018 June 2012National Stadium, WarsawPOLGRE10028 June 2012Stadion Miejski (Wroclaw)RUSCZE100312 June 2012Stadion Miejski (Wroclaw)GRECZE100412 June 2012National Stadium, WarsawPOLRUS... goal …

@游戏行业er!MongoDB广州线下沙龙邀您报名!

随着游戏和应用程序的发展&#xff0c;数据变得越来越重要。在为您的下一个游戏选择数据库时&#xff0c;数据库管理者常常会面对灵活性、可扩展性、可靠性、运营效率等问题或挑战。 MongoDB在游戏开发领域有着广泛的应用&#xff0c;灵活数据模型可以存储和处理各种类型的数据…

C++--String类

系列文章目录 文章目录 目录 系列文章目录 文章目录 前言 一、为什么要学习string 1.c语言的字符串 2.OJ上的使用 二、string类的接口介绍 1.string简介 2.string构造成员函数 3.operator函数 4.string容器size和length 5.重载operator[]和引用返回的意义 5.1 oper…

嫦娥六号揭秘真相:阿波罗登月是真是假?一文终结所有疑问!

近期&#xff0c;嫦娥六号的成功发射如同璀璨的星辰&#xff0c;再次将人们的视线聚焦于浩瀚的宇宙&#xff0c;与此同时&#xff0c;网络上关于美国阿波罗登月是否造假的争议也如潮水般涌现。一些声音宣称&#xff0c;嫦娥六号的发射为揭示美国阿波罗登月任务的真实性提供了关…

Java面试八股之String类的常用方法有哪些

Java中String类的常用方法有哪些 获取字符串信息&#xff1a; length()&#xff1a;返回字符串的字符数。 isEmpty()&#xff1a;判断字符串是否为空&#xff08;即长度为0&#xff09;。 访问单个字符&#xff1a; charAt(int index)&#xff1a;返回指定索引处的字符。 …

InstantStyle —— 文本到图像生成中的风格保持新突破

在人工智能领域&#xff0c;文本到图像生成&#xff08;Text-to-Image Generation&#xff09;技术正迅速发展&#xff0c;其应用范围从娱乐到专业设计不断扩展。然而&#xff0c;风格一致性生成一直是该领域的一个技术难题。最近&#xff0c;InstantX团队提出了一种名为Instan…

GEVernova推出GEV新能源平台,引领新能源未来

近日&#xff0c;全球领先的能源设备制造和服务公司 GE Vernova 宣布推出 GEV 新能源平台&#xff0c;这是一个将金融、科技和产业深度融合的全新投资平台。GEV 新能源平台旨在为用户提供一站式可持续新能源投资解决方案&#xff0c;助力全球新能源转型和可持续发展。 新能源已…

vs-qt中无法加载qsqlite驱动,但是单独新建demo测试却又是正常的。。。

开发环境: Vs2015 + qt5.12 背景: 接手了一个项目,可以编译过去,也可以运行,, 但是登录一直失败,,但是数据库文件也是正常的。。。 最主要的是环境和同事的是一样的,,,但是他那边可以加载成功,我这边不可以。。 后来单独在vs中创建了一个demo,用来测试QSqlData…

如何高效管理微信?快速掌握捷径!

对于那些需要管理多个微信号的人来说&#xff0c;如何高效地管理这些账号成为了一个难题。今天&#xff0c;就给大家分享一个管理多个微信号的捷径——微信管理系统。 通过微信管理系统&#xff0c;你可以轻松实现高效管理多个微信号&#xff0c;一起来看看吧&#xff01; 首…

一文汇总对比英伟达、AMD、英特尔显卡GPU

‍‍&#x1f3e1;博客主页&#xff1a; virobotics(仪酷智能)&#xff1a;LabVIEW深度学习、人工智能博主 &#x1f4d1;上期文章&#xff1a;『【仪酷LabVIEW AI工具包案例】使用LabVIEW AI工具包YOLOv5结合Dobot机械臂实现智能垃圾分类』 &#x1f37b;本文由virobotics(仪酷…

C语言/数据结构——每日一题(环形链表)

一.前言 今天在力扣上刷到一道链表题——环形链表https://leetcode.cn/problems/linked-list-cycle 想着和大家们分享一下。让我们直接开始今天的分享吧。、 二.正文 1.1题目描述 1.2题目分析 这道题是想让我们做出分析&#xff0c;该链表是不是带环链表&#xff0c;如果是…

mac定时任务、自启动任务

https://quail.ink/mynotes/p/mac-startup-configuration-detailed-explanation <?xml version"1.0" encoding"UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.d…

DIFT:Emergent Correspondence from Image Diffusion # 论文阅读

URL https://arxiv.org/pdf/2306.03881 主页&#xff1a;https://diffusionfeatures.github.io/ 代码&#xff1a;https://github.com/Tsingularity/dift TD;DR 23 年 6月 cornell 大学的文章&#xff0c;任务是做图片的特征匹配&#xff08;关联&#xff09;&#xff0c;特…

Github入门10问,收藏~

Github是Python开发中最常用到的工具和资源&#xff0c;Github上Python相关的仓库多达300多万个&#xff0c;但有很多人还不知道怎么去使用Github&#xff0c;这里来通过10个问题来科普下。 什么是GitHub&#xff1f;为什么要学习使用GitHub&#xff1f;如何创建GitHub账户&…

VTK —— 三、标准格式 - 示例1 - 读取建模不同格式模型(支持.ply、.vtp、.obj、.stl、.vtk、.g等模型格式)(附完整源码)

代码效果 本代码编译运行均在如下链接文章生成的库执行成功&#xff0c;若无VTK库则请先参考如下链接编译vtk源码&#xff1a; VTK —— 一、Windows10下编译VTK源码&#xff0c;并用Vs2017代码测试&#xff08;附编译流程、附编译好的库、vtk测试源码&#xff09; 教程描述 本…

宝塔面板各种疑难杂症处理命令教程

下载地址&#xff1a;宝塔面板各种疑难杂症处理命令教程 这份宝塔面板各种疑难杂症处理命令教程&#xff0c;可以解决市面上遇到的各种难题&#xff0c;建议有技术能行的下载使用&#xff0c;小白也可以下载来学习可以帮助你解决宝塔面板遇到的各种难题

Java面试八股之什么是Java反射

什么是Java反射 基本概念 反射是Java语言的一个重要特性&#xff0c;它允许我们在运行时分析类、接口、字段、方法等组件的信息&#xff0c;并能够动态地操作这些组件&#xff0c;包括创建对象、调用方法、访问和修改字段值等。简单来说&#xff0c;反射提供了在程序运行时对…

镊子蜡烛如何抓住反转进行交易?昂首资本2步抓住反转

很多投资者通过之前的文章知道镊子烛台图&#xff0c;甚至可以通过镊子烛台图有多倍收益&#xff0c;但是很多投资者又迷惑了&#xff0c;为什么我没有通过镊子烛台图获得收益&#xff0c;甚至有时还会亏损收手。其实事情很容易理解&#xff0c;Anzo Capital昂首资本认为那是因…

MES管理系统在柔性制造中有何重要作用

在当今这个瞬息万变的商业环境中&#xff0c;制造业正经历着一场前所未有的转型。消费者需求的多样化和市场动态的快速变化要求企业必须具备高度的灵活性和适应性。为了应对这些挑战&#xff0c;柔性制造策略应运而生&#xff0c;它以其快速响应和灵活调整的能力&#xff0c;成…