十二、正则表达式、元字符、替换修饰符、手势和对话框插件、字符串截取

AI时代敏捷开发新范式——意图驱动开发IDD 具体的功能代码、单元测试、集成测试用例,以及最终可运行的、支持PlantUML的Markdown转Word工具新版本。:业务方(如技术文档团队)反馈,现有的Markdown转Word工具在处理包含PlantUML代码块的文档时,无法正确生成图表,导致技术方案、架构图等关键信息丢失,严重影响了文档交付质量和团队效率。这不仅带来了交付周期显著缩短、资源效能倍增的可观收益,更深远的意义在于,它描绘了未来软件工业化、智能化的新图景:一个由精准意图驱动、AI自主执行、人类智慧引领的敏捷、高效、高质的新世界。 阅读详情

1. 正则表达式

1.1 基本使用

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <!-- 
    正则表达式(Regular Expression)是一种字符串匹配的模式(规则)
    ⚫ 使用场景:
    ➢ 例如验证表单:手机号表单要求用户只能输入11位的数字 (匹配)
    ➢ 过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)
  -->
  <script>
    // 1. 定义规则 其中/ /是正则表达式字面量;正则表达式也是对象
    const reg1 = /JS/
    const reg2 = new RegExp('JS')

    let str1 = 'JS学习'
    let str2 = 'TS学习'
    let str3 = '学习'

    // 2. 使用正则 test()方法 用来查看正则表达式与指定的字符串是否匹配,返回布尔型数据
    console.log(reg1.test(str1)) // true
    console.log(reg1.test(str2)) // false
    console.log(reg1.test(str3)) // false

    console.log(reg2.test(str1)) // true
    console.log(reg2.test(str2)) // false
    console.log(reg2.test(str3)) // false
  </script>
</body>

</html>

1.2 元字符

1.2.1 边界符

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <!-- 
    普通字符:普通字符只能够匹配字符串中与它们相同的字符
    元字符(特殊字符):是一些具有特殊含义的字符,极大提高了灵活性和强大的匹配功能(边界符 量词 范围 字符类)
  -->
  <!-- 
    边界符: 定义位置规则,必须用什么开头,用什么结尾
    ^ 开始 ; $ 结束 ; ^和$在一起,表示必须是精确匹配
  -->
  <script>
    const reg1 = /JS/
    const reg2 = /^JS/
    const reg3 = /JS$/
    const reg4 = /^JS$/

    let str1 = 'JS学习'
    let str2 = '学习JS'
    let str3 = 'JS'

    console.log(reg1.test(str1)) // true

    console.log(reg2.test(str1)) // true
    console.log(reg2.test(str2)) // false

    console.log(reg3.test(str1)) // false
    console.log(reg3.test(str2)) // true

    console.log(reg4.test(str2)) // false
    console.log(reg4.test(str3)) // true
  </script>
</body>

</html>

1.2.2 量词

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <!-- 量词:用来设定某个模式重复次数 -->
  <script>
    // 有开始结束,精确匹配
    // *:重复>=0 次
    const reg1 = /^钱*$/
    console.log(reg1.test('')) // t
    console.log(reg1.test('钱')) // t
    console.log(reg1.test('111')) // f
    console.log('-------------------')

    // +:重复>=1 次
    const reg2 = /^钱+$/
    console.log(reg2.test('')) // f
    console.log(reg2.test('钱')) // t
    console.log(reg2.test('钱钱')) // t
    console.log('-------------------')

    // ?:重复0次或1次
    const reg3 = /^钱?$/
    console.log(reg3.test('')) // t
    console.log(reg3.test('钱')) // t
    console.log(reg3.test('钱钱')) // f
    console.log('-------------------')

    // {n}:重复n次
    const reg4 = /^钱{3}$/
    console.log(reg4.test('钱钱')) // f
    console.log(reg4.test('钱钱钱')) // t
    console.log('-------------------')

    // {n,}:重复>=n 次
    const reg5 = /^钱{3,}$/
    console.log(reg5.test('钱钱')) // f
    console.log(reg5.test('钱钱钱')) // t
    console.log(reg5.test('钱钱钱钱')) // t
    console.log('-------------------')

    // {n,m}:重复n~m 次(包含n,m) 逗号左右两侧千万不要出现空格
    const reg6 = /^钱{3,5}$/
    console.log(reg6.test('钱钱')) // f
    console.log(reg6.test('钱钱钱')) // t
    console.log(reg6.test('钱钱钱钱钱')) // t

  </script>
</body>

</html>

1.2.3 范围

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <!-- 
    范围:表示字符的范围,定义的规则限定在某个范围,
    比如只能是英文字母,或者数字等等,用 [] 表示范围

    [abc] 匹配包含的单个字符。也就是只有 a || b || c 这三个单字符返回true,可以理解为多选1
    [a-z] 连字符。来指定字符范围。[a-z] 表示 a 到 z 26个英文字母 
    [^abc] 取反符。[^a-z] 匹配除了小写字母以外的字符
  -->
  <script>
    // 单个字符
    // 1. 多选1
    const reg1 = /[abc]/
    console.log(reg1.test('a')) // true
    console.log(reg1.test('ac')) // true
    console.log(reg1.test('cd')) // true
    console.log(reg1.test('de')) // false
    console.log('--------------')

    // 2. 连字符
    /* 
      ➢ [a-z] 表示 a 到 z 26个英文字母都可以
      ➢ [a-zA-Z] 表示大小写都可以
      ➢ [0-9] 表示 0~9 的数字都可以
    */
    const reg2 = /[a-f]/
    console.log(reg2.test('a')) // true
    console.log(reg2.test('ac')) // true
    console.log(reg2.test('ch')) // true
    console.log(reg2.test('hj')) // false
    console.log('--------------')

    // 3. 取反符
    const reg3 = /[^abc]/
    console.log(reg3.test('a')) // false
    console.log(reg3.test('ac')) // false
    console.log(reg3.test('cd')) // true
    console.log(reg3.test('de')) // true
  </script>
</body>

</html>

案例1_验证用户名

<!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>验证用户名案例</title>
  <style>
    dt,
    dd {
      margin: 0;
      position: relative;
    }

    dl {
      display: flex;
      width: 600px;
      height: 30px;
      line-height: 30px;
    }

    dl dt {
      margin-right: 5px;
    }

    dl input {
      width: 269px;
      height: 28px;
      padding-left: 5px;
      border: 1px solid #ccc;
      outline: none;
      background: transparent;
      line-height: 30px;
      border-radius: 5px;
    }

    .tip {
      display: none;
      position: relative;
      width: 220px;
      height: 30px;
      margin-left: 15px;
      border: 1px solid #f59fb1;
      color: #d93c3c;
      text-align: center;
      font-size: 14px;
      background-color: #fff2f5;
      border-radius: 5px;
    }

    .tip::before {
      content: '';
      position: absolute;
      top: 50%;
      left: -6px;
      width: 10px;
      height: 10px;
      background-color: #fff2f5;
      border-left: 1px solid #f59fb1;
      border-bottom: 1px solid #f59fb1;
      transform: translateY(-50%) rotate(45deg);
    }

    span {
      position: absolute;
      top: 9px;
      right: 10px;
      width: 15px;
      height: 15px;
    }

    .right {
      background: url(./images/right.png) no-repeat;
    }

    .wrong {
      background: url(./images/error1.png) no-repeat;
    }
  </style>
</head>

<body>
  <dl>
    <dt>用户名:</dt>
    <dd><input type="text" class="uname"><span></span></dd>
    <dd class="tip">输入6~16位数字字母-_组成</dd>
  </dl>

  <!-- 
    用户名验证案例
      需求:用户名要求用户英文字母,数字,下划线或者短横线组成,
      并且用户名长度为 6~16 位 /^[a-zA-Z0-9_-]{6-16}$/
  -->
  <script>
    const ipt = document.querySelector('.uname')
    const rORw = document.querySelector('span')
    const tip = document.querySelector('.tip')
    /* 
      拓展补充:
      ➢ blur 事件:当元素失去焦点时触发(不论表单元素的值是否发生改变)
      ➢ change 事件:元素失去焦点并且表单元素的值发生改变才会触发
    */
    const reg = /^[a-zA-Z0-9-_]{6,16}$/
    ipt.addEventListener('change', function () {
      if (reg.test(this.value)) {
        /* rORw.classList.add('right')
        rORw.classList.remove('wrong') */
        // span只能有一个类名,right或wrong,直接className替换即可
        rORw.className = 'right'
        tip.style.display = 'none'
      } else {
        /* rORw.classList.remove('right')
        rORw.classList.add('wrong') */
        rORw.className = 'wrong'
        tip.style.display = 'block'
      }
    })
  </script>
</body>

</html>

1.2.4 字符类

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <!-- 
    字符类:某些常见模式的简写方式,区分字母和数字

    \d 匹配0-9之间的任一数字,相当于[0-9]
    \D 匹配所有0-9以外的字符,相当于[^0-9]
    \w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]
    \W 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]
    \s 匹配空格(包括换行符、制表符、空格符等),相等于[\t\r\n\v\f]
    \S 匹配非空格的字符,相当于[^\t\r\n\v\f] 
  -->
  <script>
    // 日期格式(简易 不规范)
    const reg = /^\d{4}-\d{1,2}-\d{1,2}$/
    console.log(reg.test('2024-11-26')) // true
    console.log(reg.test('2025-1-1')) // true
  </script>
</body>

</html>

1.3 替换和修饰符

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>

  <!-- 
    替换和修饰符
    replace 替换方法,可以完成字符的替换
      字符串.replace(/正则表达式/, '替换的文本')

    修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等
      /表达式/修饰符
      ➢ i 是单词 ignore 的缩写,正则匹配时字母不区分大小写
      ➢ g 是单词 global 的缩写,匹配所有满足正则表达式的结果
  -->
  <script>
    const str = '欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神'
    // 懒惰模式(默认),只匹配第一个,后面忽略
    const newStr1 = str.replace(/前端/, '鸿蒙')
    // replace 返回一个新的字符串,不修改原字符串
    console.log(str) // 欢迎大家学习前端,相信大家一定能学好前端,都成为前端大神
    console.log(newStr1) // 欢迎大家学习鸿蒙,相信大家一定能学好前端,都成为前端大神
    // g 匹配所有满足正则表达式的结果
    const newStr2 = str.replace(/前端/g, '鸿蒙')
    console.log(newStr2) // 欢迎大家学习鸿蒙,相信大家一定能学好鸿蒙,都成为鸿蒙大神
  </script>
</body>

</html>

案例2_隐藏手机号中间四位

<!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>隐藏手机号中间四位案例.</title>
  <style>
    .wrapper {
      width: 840px;
      height: 420px;
      background: url(./images/bg01.jpg) no-repeat center / cover;
      padding: 100px 250px;
      box-sizing: border-box;
    }

    .wrapper strong {
      font-size: 50px;
    }

    .wrapper span {
      color: #b10e0d;
    }
  </style>
</head>

<body>
  <div class="wrapper">
    <strong>年会抽奖</strong>
    <h1>获奖手机号:<span class="phone">???</span></h1>
  </div>

  <!-- 隐藏手机号中间四位案例 -->
  <script>
    let tel = '13866668888'

    // 把手机号利用正则利用小括号划分为三部分
    const reg = /^(\d{3})(\d{4})(\d{4})$/

    // 在replace中,$1 对应第一个小括号内容,依次类推
    let str1 = tel.replace(reg, '$1****$3')

    // ${} -- 模板字符串${变量或表达式}
    // 字符串重复使用:字符串.repeat(次数) 实现
    let str2 = tel.replace(reg, `$1${'*'.repeat(4)}$3`)

    document.querySelector('.phone').innerHTML = str1
  </script>
</body>

</html>

2. JS插件

2.1 AlloyFinger 手势插件

<!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>AlloyFinger手势插件</title>
  <style>
    .nav {
      width: 200px;
      height: 40px;
      border: 3px solid pink;
    }

    .item {
      width: 250px;
      height: 40px;
      line-height: 40px;
      background-color: skyblue;
      transition: all .3s;
    }

    .active {
      transform: translateX(-50px);
    }
  </style>
</head>

<body>
  <div class="nav">
    <div class="item">
      AlloyFinger是腾讯AlloyTeam 开发
    </div>
  </div>

  <!-- AlloyFinger 是腾讯 AlloyTeam 团队开源的超轻量级 Web 手势插件,为元素注册各种手势事件 -->
  <!-- 将AlloyFinger库引入当前文件 -->
  <!-- 
  配置
    new AlloyFinger(element, { // element 是给哪个元素做滑动事件
      swipe: function (e) {
        // 滑动的时候要做的事情 e.direction 可以判断上下左右滑动 Left Right 等
      }
    })
  -->
  <script src="./alloy_finger.js"></script>
  <script>
    const item = document.querySelector('.item')
    new AlloyFinger(item, {
      swipe: function (e) {
        if (e.direction === 'Left') {
          item.classList.add('active')
        } else if (e.direction === 'Right') {
          item.classList.remove('active')
        }
      },
      // 手指触摸
      touchStart: function () {
        console.log('touchStart')
      },
      // 手指移动
      touchMove: function () {
        console.log('touchMove')
      },
      // 手指移开
      touchEnd: function () {
        console.log('touchEnd')
      }
    })
  </script>
</body>

</html>

2.2 M端事件

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .box {
      width: 300px;
      height: 300px;
      background-color: pink;
    }
  </style>
</head>

<body>
  <div class="box"></div>

  <!-- 
  M端(移动端)有自己独特的地方。比如触屏事件 touch(也称触摸事件)。
  touch 对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。
  触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。
  
  触屏touch事件
    touchstart 手指触摸到一个DOM元素时触发
    touchmove 手指在一个DOM元素上滑动时触发
    touchend 手指从一个DOM元素上移开时触发
  -->
  <script>
    const box = document.querySelector('.box')
    box.addEventListener('touchstart', function () {
      console.log('touchstart')
    })
    box.addEventListener('touchmove', function () {
      console.log('touchmove')
    })
    box.addEventListener('touchend', function () {
      console.log('touchend')
    })
  </script>
</body>

</html>

2.3 a11y-dialog 对话框插件

<body>
  <!-- 按钮 -->
  <div class="btns">
    <button class="btn btn1">添加</button>
  </div>

  <!-- a11y -->
  <!-- 1. 准备对话框容器 -->
  <div class="dialog-container" id="dialog" aria-hidden="true">
    <!-- 2. 底部蒙层 -->
    <div class="dialog-overlay" data-a11y-dialog-hide></div>
    <!-- 3. 对话框结构 -->
    <div class="dialog-content">
      <!-- 4. 关闭按钮 -->
      <button type="button" class="dialog-close" data-a11y-dialog-hide>
        &times;
      </button>
      <!-- 5. 标题 -->
      <h1>测试对话框</h1>
      <!-- 6. 内容 -->
      <p>好看的对话框</p>
    </div>
  </div>

  <!-- <script src="https://cdn.jsdelivr.net/npm/a11y-dialog@8/dist/a11y-dialog.min.js"></script> -->
  <script src="./a11y-dialog.js"></script>
  <script>
    const btn1 = document.querySelector('.btn1')
    // 获取对话框DOM容器
    const element = document.querySelector('#dialog')
    // 实例化对话框
    const dialog = new A11yDialog(element)

    btn1.addEventListener('click', function () {
      // 实例对话框调用 show 方法可以显示对话框
      dialog.show()
    })
  </script>
</body>

3. 字符串截取

  <script>
    const str = '我们都是前端大神啊'
    // 字符串截取

    // 1. substring
    // 最后一个字符
    console.log(str.substring(str.length - 1)) // 啊
    // 第一个字符
    console.log(str.substring(0, 1)) // 我

    // 2. str[] 字符串也有索引,
    console.log(str[0]) // 我
  </script>

4. 综合案例_移动端通讯录

<!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>通讯录案例</title>
  <link rel="stylesheet" href="./iconfont/iconfont.css" />
  <link rel="stylesheet" href="./index.css" />
</head>

<body>
  <div class="address-header">
    通讯录
    <i class="iconfont icon-tianjiayonghu"></i>
  </div>
  <div class="address-book">
    <!-- 添加item 核心区域-->
    <!-- <div class="item">
      <p class="circle">华</p>
      <p class="name">刘德华</p>
      <p class="tel">15300588305</p>
      <a class="del" href="javascript:;">
        <i class="iconfont icon-shanchutianchong" data-index="0"></i>
      </a>
    </div> -->
  </div>

  <button id="add" class="btn-add">添加联系人</button>

  <!-- 模态框-添加联系人 -->
  <div class="dialog-container" id="modal" aria-hidden="true" aria-labelledby="my-dialog-title"
    aria-describedby="my-dialog-description">
    <div class="dialog-overlay" data-a11y-dialog-hide></div>
    <div class="dialog-content" role="document">
      <h1 id="my-dialog-title" class="title">
        添加联系人
        <button type="button" aria-label="Close this dialog window" class="el-dialog__headerbtn dialog-close"
          data-a11y-dialog-hide>
          取消
        </button>
      </h1>

      <!-- 联系人表单 -->
      <div class="address-footer">
        <input id="name" type="text" placeholder="请输入姓名" />
        <input id="tel" type="text" placeholder="请输入手机号" />
        <button class="btn-ok" id="btnOK">确认</button>
      </div>
    </div>
  </div>

  <!-- 引入手势插件 -->
  <script src="./js/alloy_finger.js"></script>
  <!-- 引入弹窗插件 -->
  <script src="./js/a11y-dialog.js"></script>
  <script>
    // 本地存储
    let arr = JSON.parse(localStorage.getItem('contacts')) || []
    // 初始化数据
    /* let arr = [
      { name: '周杰伦', tel: '13411112222' },
      { name: '刘德华', tel: '13511112222' },
      { name: '张学友', tel: '13711112222' },
      { name: '岳云鹏', tel: '13911112222' },
      { name: '迪丽热巴', tel: '13911112222' }
    ] */

    const addressBook = document.querySelector('.address-book')
    // 渲染业务
    function render(data = arr) {
      let str = data.map((item, index) => {
        const { name, tel } = item
        return `
          <div class="item">
            <p class="circle">${name.substring(name.length - 1)}</p>
            <p class="name">${name}</p>
            <p class="tel">${tel}</p>
            <a class="del" href="javascript:;">
              <i class="iconfont icon-shanchutianchong" data-index="${index}"></i>
            </a>
          </div>
        `
      }).join('')
      addressBook.innerHTML = str

      /* 调用滑动功能
      每次 render 函数被调用后都会被执行,
      确保对新生成的 .item 元素进行了正确的事件绑定。 */
      swipe()
    }
    render()

    // 滑动业务
    // 滑动业务事件委托做不了,e.target值不确定 p div? --> forEach做
    // 要在渲染的时候准备好滑动功能等待用户滑动 -- 定义滑动函数,渲染函数中调用
    function swipe() {
      // forEach 遍历添加事件监听
      // 获取items元素若放到顶部,此时render函数未调用,HTML未填充item元素,获取元素失败 --> 滑动功能实现失败
      const items = document.querySelectorAll('.address-book .item')
      items.forEach(item => {
        new AlloyFinger(item, {
          swipe: function (e) {
            // console.log(e)
            if (e.direction === 'Left') {
              // 排他
              // 1. 页面打开默认有自带active类名,下行代码可行;默认无active找不到元素返回为空,控制台classList报错
              // document.querySelector('.address-book .active').classList.remove('active')
              // 2. css选择器书写错误 item和active同级类名,找不到item下的active符合条件的元素
              // document.querySelector('.item .active')?.classList.remove('active')
              const active = document.querySelector('.address-book .active')
              // 3.1 正确写法一 if判断
              /* if (active) {
                active.classList.remove('active')
              } */
              // 3.2 正确写法二 ?可选
              // active?.classList.remove('active')
              // 3.3 正确写法三 逻辑中断
              active && active.classList.remove('active')

              item.classList.add('active')
            } else if (e.direction === 'Right') {
              item.classList.remove('active')
            }
          }
        })
      })
    }

    // 删除业务 事件委托
    addressBook.addEventListener('click', function (e) {
      // console.log(e.target.dataset.index)
      if (e.target.classList.contains('icon-shanchutianchong')) {
        // confirm() 弹窗 返回值为布尔型
        let isDel = confirm('确定要删除嘛?')
        if (isDel) {
          arr.splice(e.target.dataset.index, 1)
          localStorage.setItem('contacts', JSON.stringify(arr))
          render()
        } else {
          document.querySelector('.active').classList.remove('active')
        }
      }
    })

    // 新增业务
    const btnAdd = document.querySelector('.btn-add')
    // 获取对话框DOM容器
    const modal = document.querySelector('#modal')
    // 实例化对话框
    const dialog = new A11yDialog(modal)
    btnAdd.addEventListener('click', function () {
      dialog.show()
    })

    const btnOK = document.querySelector('#btnOK')
    const uname = document.querySelector('#name')
    const tel = document.querySelector('#tel')
    btnOK.addEventListener('click', function () {
      // 验证数据合法?
      let unameReg = /^(?:[\u4e00-\u9fa5·]{2,16})$/
      let telReg = /^(?:(?:\+|00)86)?1[3-9]\d{9}$/
      let addName = uname.value
      let addTel = tel.value

      if (!addName.trim() || !addTel.trim()) {
        alert('不能为空')
        return
      }
      if (!unameReg.test(addName)) {
        alert('姓名输入错误')
        return
      }
      if (!telReg.test(addTel)) {
        alert('电话输入错误')
        return
      }

      arr.unshift({ name: addName, tel: addTel })
      localStorage.setItem('contacts', JSON.stringify(arr))
      render()
      // 关闭添加联系人页面
      dialog.hide()
      uname.value = ''
      tel.value = ''
    })
  </script>
</body>

</html>

5. 作业

5.1 软考个人信息提交

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="index.css">

</head>

<body>
  <header>
    <h1>
      <img src="https://bm.ruankao.org.cn/asset/image/public/logo.png" alt="">
      <span>全国计算机技术与软件专业技术资格(水平)考试</span>

      <span class="address">当前考区:北京</span>
    </h1>

    <div>
      <span class="hello">xxx,您好!</span>
    </div>
  </header>

  <main>
    <section>
      <h3>基本信息</h3>
      <form action="#">
        <div class="form-item is-required">
          <label for="username">
            姓名:
          </label>
          <div class="form-item-content">
            <input class="hm-input" type="text" id="username">
            <!-- <div class="form-error hide">用户名校验不通过,请输入1-4位的汉字</div> -->
            <div class="form-error">用户名校验不通过,请输入1-4位的汉字</div>
          </div>
        </div>
        <div class="form-item is-required">
          <label for="idcard">
            身份证:
          </label>
          <div class="form-item-content">
            <input class="hm-input" type="text" id="idcard">
            <!-- <div class="form-error hide">请输入合法的身份证格式</div> -->
            <div class="form-error">请输入合法的身份证格式</div>
          </div>
        </div>
        <div class="form-item is-required">
          <label for="age">
            年龄:
          </label>
          <div class="form-item-content">
            <input class="hm-input" type="text" id="age">
            <!-- <div class="form-error hide">请输入数字</div> -->
            <div class="form-error">请输入数字</div>
          </div>
        </div>
        <div class="form-item is-required">
          <label for="mobile">
            手机号:
          </label>
          <div class="form-item-content">
            <input class="hm-input" type="text" id="mobile">
            <!-- <div class="form-error hide">请输入合法的手机号</div> -->
            <div class="form-error">请输入合法的手机号</div>
          </div>
        </div>

        <button class="submit">提交</button>
      </form>
    </section>
  </main>

  <!-- 
  需求如下:
  点击提交时,对表单进行数据格式校验:
    校验不通过,显示错误提示
    校验通过,跳转到成功页面
  -->
  <script>
    const form = document.querySelector('form')
    const username = document.querySelector('#username')
    const idcard = document.querySelector('#idcard')
    const age = document.querySelector('#age')
    const mobile = document.querySelector('#mobile')

    // 正则
    const regUsername = /^(?:[\u4e00-\u9fa5]{1,4})$/
    const regIdcard = /^\d{6}((((((19|20)\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|(((19|20)\d{2})(0[13578]|1[02])31)|((19|20)\d{2})02(0[1-9]|1\d|2[0-8])|((((19|20)([13579][26]|[2468][048]|0[48]))|(2000))0229))\d{3})|((((\d{2})(0[13-9]|1[012])(0[1-9]|[12]\d|30))|((\d{2})(0[13578]|1[02])31)|((\d{2})02(0[1-9]|1\d|2[0-8]))|(([13579][26]|[2468][048]|0[048])0229))\d{2}))(\d|X|x)$/
    const regAge = /^\d{1,2}$/
    const regMobile = /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[1589]))\d{8}$/

    function REG(reg, el) {
      return reg.test(el.trim())
    }
    /* console.log(REG(regUsername, '小红')) // t
    console.log(REG(regUsername, '红')) // t
    console.log(REG(regUsername, '12352')) // f */

    form.addEventListener('submit', function (e) {
      if (REG(regUsername, username.value)) {
        // nextElementSibling 获取节点的下一个兄弟节点
        username.nextElementSibling.classList.add('hide')
      }
      if (REG(regIdcard, idcard.value)) {
        idcard.nextElementSibling.classList.add('hide')
      }
      if (REG(regAge, age.value)) {
        age.nextElementSibling.classList.add('hide')
      }
      if (REG(regMobile, mobile.value)) {
        mobile.nextElementSibling.classList.add('hide')
      }

      // console.log(document.querySelectorAll('.hide'))
      // console.log(document.querySelectorAll('.hide').length) // '4'
      // console.log(document.querySelectorAll('.hide').length == '4')

      // 阻止表单默认行为
      e.preventDefault()
      if (document.querySelectorAll('.hide').length == '4') {
        // console.log('success')
        location.href = './success.html'
      }
    })
  </script>
</body>

</html>

5.2 仿outlook邮箱

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="./index.css">
  <link rel="stylesheet" href="./fonts/iconfont.css">
</head>

<body>
  <header>
    <span class="iconfont icon-hanbaobao"></span>
    <span>收件箱</span>
    <img src="./imgs/default-avatar.png" alt="">
  </header>
  <ul class="mail-list">
    <!-- <li class="unread">
      <div class="group">
        <div class="status">
          标记已读
        </div>
        <article>
          <img src="./imgs/default-avatar.png" alt="">
          <div class="mail-info">
            <div>
              <span class="from">Jack</span>
              <time>2023/10/1</time>
            </div>
            <p>您好, 您之所以会收到此邮件,是因为我们正在更新 Microsoft 服务协议,该协议适用于您所使用的一个或多个 Microsoft
              产品或服务。我们之所以进行这些更新,是为了阐明我们的条款并确保这些条款仍对您保持透明。</p>
          </div>
        </article>
      </div>
    </li> -->
  </ul>

  <!-- <script src="https://unpkg.com/alloyfinger@0.1.16/alloy_finger.js"></script> -->
  <script src="../alloy_finger.js"></script>
  <script src="data.js"></script>

  <script>
    const list = document.querySelector(".mail-list")
    function render(data = mails) {
      let str = data
        .map((el, index) => {
          const {
            from: { username, avatar },
            time,
            content,
            readStatus,
          } = el
          return `
            <li class="unread">
              <div class="group">
                <div class="status">
                  标记已读
                </div>
                <article>
                  <img src="${avatar}" alt="">
                  <div class="mail-info">
                    <div>
                      <span class="from">${username}</span>
                      <time>${time}</time>
                    </div>
                    <p>${content}/p>
                  </div>
                </article>
              </div>
            </li>
          `
        })
        .join("")
      list.innerHTML = str

      swipefn()
    }
    render()

    // 滑动发生时 内容内标签变化 需再次渲染可实现滑动 封装滑动功能函数 渲染函数内调用
    function swipefn() {
      // 新增需求:向右滑动,出现操作区块,点击可修改邮件的阅读状态
      const lis = document.querySelectorAll(".mail-list li")
      // previousElementSibling 上一个兄弟节点
      lis.forEach((item) => {
        console.log(item.tagName) // LI
        // 查找子节点的子节点
        const status = item.children[0].children[0]
        // console.log(status)
        new AlloyFinger(item, {
          // 
          swipe: function (e) {
            // console.log(e.target)
            if (e.direction === "Right") {
              item.classList.toggle('active')
              item.classList.contains('read')
                ? status.innerHTML = '标记未读'
                : status.innerHTML = '标记已读'
            }
          },
          touchStart: function (e) {
            if (e.target.classList.contains('status')) {
              item.classList.toggle('active')
              item.classList.toggle('read')
              status.innerHTML = '标记未读'
            }
          }
        })
      })
    }
  </script>
</body>

</html>

FFMPEG音频开发: Linux下采集摄像头(使用V4L2框架)数据录制成MP4视频保存到本地 一、环境介绍 操作系统介绍:ubuntu 18.04 FFMPEG版本: 4.4.2 摄像头: USB摄像头、虚拟机挂载本机自带摄像头 二、FFMPEG与X264下载编译 X264下载地址: http://www.videolan.org/developers/x264.html FFMPEG下载地址:https://ffmpeg.org/download.html Yasm ... 阅读详情

相关推荐

Android Studio安装常见问题详解——Android Emulator Hypervisor Driver for AMD Processors installation failed.

目录一、问题描述二、解决方案2.1 开启CPU虚拟化2.2 禁用Hyper-V2.3 使用管理员命令行在驱动程序包中执行“silent_install.bat” 一、问题描述 新买的AMD轻薄本,在安装Android Studio时遇到问题: Android Emulator Hypervisor Driver for AMD Processors installation failed. 笔记本配置为: 二、解决方案 2.1 开启CPU虚拟化 设置虚拟化的步骤这里不进行详细介绍了。如果需要,可以自行百

Wendy的博客 4万+

【正则表达式】修饰符与替换详解

修饰符(Modifiers)是正则表达式中的一种特殊字符,用于控制匹配模式的行为。通过添加修饰符,开发者可以更灵活地控制正则表达式的匹配规则。例如,修饰符可以让匹配忽略大小写、进行全局查找或多行匹配等。正则表达式的替换操作允许我们根据匹配的模式修改字符串中的内容。通常,替换操作通过正则表达式匹配到部分内容后,用新的字符串或函数结果来替换原有的匹配部分。正则表达式中的修饰符与替换功能为开发者提供了灵活且强大的文本处理工具。

lph159的博客 1879

新手必看:如何用T265和ROS实现无人机室内精准定位(附PX4参数配置)

本文详细介绍了如何使用Intel Realsense T265和ROS实现无人机室内精准定位,包括硬件准备、ROS数据流架构设计、PX4参数配置及系统验证。特别针对视觉SLAM技术在室内环境中的应用,提供了从零搭建到进阶优化的全流程解析,适合无人机开发新手快速上手。

weixin_30642561的博客 405

正则修饰符、用敏感词库替换

正则修饰符 ● 语法 JavaScript复制代码 /正则内容/修饰符 // 例 /[a-z]/i 忽略大小写的 ○i:忽略大小写 ○g:全局匹配 ○两个一起写,写成 ig 或 gi 就代表 既忽略大小写,也全局匹配 ● 替换 ○ 字符串的replace,可以替换字符串内容 str.replace(正则表达式, 要替换的内容) // 例 let str = 'oooOOO哈哈哈OOOooo' str = str.replace(/o/ig, '') // 把所有的

gaoyan426926的博客 469

数字电路实验避坑指南:如何正确搭建主从JK触发器测试电路(附Proteus仿真)

本文详细解析了主从JK触发器的工作原理及实验搭建指南,重点解决了常见的Catching Problem现象,并提供了Proteus仿真优化方案。通过元器件选型、电路连接步骤和常见错误排查,帮助读者正确搭建测试电路,确保数字电路实验的稳定性和可靠性。

weixin_30790841的博客 470

深入剖析:功率放大电路设计精髓——从理论到实践

输入信号首先被调制(通常是PWM脉宽调制)成高频开关信号,驱动功率开关管(MOSFET),再通过LC低通滤波器滤除高频分量,还原出放大的音频信号。在靠近功放板电源引脚处放置足够容量的电解电容(如100uF - 1000uF)和高频瓷片电容(如0.1uF)并联进行电源去耦,抑制低频和高频干扰,防止低频振荡(Motorboating)和高频自激。,堪称电子世界里的“能量转换器”。当输入信号在零附近(即两个器件切换导通的区域)时,由于器件的开启电压(Vbe或Vgs)不为零,输出波形会出现明显的衔接不流畅的失真。

Zihan2558的博客 1698

在网站改版中用正则表达式排查附件中的身份证号与手机号:误报、漏报与工程取舍

本文探讨在网站改版中利用正则表达式批量排查4200个附件中的身份证号与手机号。针对格式多样、人工核对耗时(约210小时)的难题,提出“先归一化后匹配”的工程策略,设计兼顾准确率与召回率的正则模式,并强调扫描件需OCR支持、Excel数字格式需文本化以避免漏检。通过构建“检测—定位—人工确认—处置留痕”闭环链路,实现从210小时到25分钟的效率跃升。文中警示误报漏报风险及落地四坑,明确适用边界:仅限固定格式敏感信息,不可替代业务判断。

bbsh2099的博客 431

SUMO仿真教程(5) —— 使用“XML“语言自定义构建路网

文章目录一.简要介绍1.node file2.edge file3.lane definitions(1)路段细分(2)邻近的对向车道(3)删除边或车道4.type file(1)简要概述(2)edge定义中引用type文件的示例(3)指定车辆种类的速度限制5.connections file(1)简要概述:(2)connection的属性参数(3)删除连接(4)设置连接的优先级(5)同一边的多个连接二.演示示例:1.自定义编写node file2.自定义编写edge file3.自定义编写type fil

weixin_50632459的博客 5017

正则表达式

在学习正则表达式的时候有没有这样的困惑,这么多符号这么记呀?某符号代表啥?某符号代表啥?某符号代表啥?某符号代表啥?某符号代表啥?

qq_44776900的博客 177

华为防火墙介绍和原理,配置详细解析

在出向外网的流量中,我们使用默认路由来指定默认的出口,并且使用nat地址转换,而在外网中,我们使用ISIS协议来进行路由的学习和更新,让外网可以访问到dmz非军事化区域的server1服务器。并进行NAT转换,实现了内部IP地址和外部IP地址之间的映射,以便内部网络可以与外部网络进行通信。网络地址转换(NAT):防火墙可实现网络地址转换,将内部私有IP地址转换成公共IP地址,以隐藏网络拓扑结构,增加网络安全性。确定安全需求:根据企业的安全需求和策略,确定防火墙的配置目标和规则。

外游者 5102

详解FreeRTOS:FreeRTOSConfig.h系统配置文件(拓展篇—1)

FreeRTOS的系统配置文件为FreeRTOSConfig.h,在配置文件中可以完成FreeRTOS的裁剪和配置,这是非常重要的一个文件,本篇博文就来讲解这个文件。

不脱发的程序猿 1548

Day30 · 正则表达式

正则表达式是匹配字符串规则的强大工具,通过 re 模块实现。掌握元字符、字符类、分组与量词,可高效完成邮箱、手机号等格式校验与提取。熟练使用 match、search、findall 等接口,结合编译优化性能,提升文本处理效率。

小嘉丶学长的博客 338

SmartFusion从FPGA到ARM(九)——串口命令解析器的实现

系列教程:SmartFusion从FPGA到ARM系列教程 前面两节介绍了MSS_UART和CoreUARTapb的使用: MSS_UART的使用 CoreUARTapb的使用 MSS_UART和CoreUARTapb都支持中断和轮询方式获取串口接收的数据,对于串口中断服务函数,有时我们需要通过不同的串口指令去执行不同的动作,下面以CoreUARTapb为例,来实现一个简单的串口命令解析器。固定串口数据帧格式,帧长度不定。 串口数据帧格式:* + 数据 + #,对于数据中为参数的,可以自定义处理函数。例

whik1194的博客 1536

正则表达式学习笔记 02:基础语法

正则表达式是描述字符匹配规则的迷你语言,由普通字符和元字符组成。普通字符直接匹配自身,而元字符如.、*、+、^、$等具有特殊含义,用于控制匹配模式。常见功能包括任意字符匹配、字符类、预定义类(如\d)、量词、位置锚点、分组与捕获、环视断言及反向引用。需注意,若要匹配元字符本身,必须使用转义符\。例如,\.可匹配字面点号。

菜鸟的专栏 185

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

VSCode 正则表达式使用指南

本文介绍了VSCode中正则表达式的使用方法,涵盖开启搜索替换、常用语法(如\w、\d、^、$)、捕获组及示例应用。通过实例演示如何删除空行、转换日期格式、提取中文字符和匹配邮箱。支持多文件全局搜索与历史记录保存,建议使用在线工具调试复杂表达式,并注意大小写敏感与特殊字符转义问题。

weixin_63043528的博客 127

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

正则表达式在线测试怎么用?先定位匹配位置再看捕获组

当正则允许「匹配空字符串」时(例如a*),引擎在任意位置都能匹配到长度为 0 的内容,于是出现标着「(空匹配)」的结果。工具会自动把扫描位置往后推一位避免死循环,这类结果本身是正常的,通常说明你的量词过于宽松。

我的编程人生 235

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

正则表达式六维解析:从入门到精通

正则表达式是描述字符串模式的规则,核心在于字符匹配、重复次数、位置边界、分组选择与转义。学习时应掌握六个维度:字符匹配(字面量、通配符、字符类)、重复规则(*、+、?、{n,m})、位置锚点(^、$、\b)、分组与引用(捕获组、反向引用)、前瞻后顾及转义。结合Java API(matches、find、group)合理使用,避免灾难性回溯与复杂解析。关键:先理解“字符长什么样”,再确定“出现几次”和“从哪到哪”,最终提取所需内容。

yanghaitao5000的博客 176

Web 版翻译者资料库

本项目是桌面版《翻译者资料库》的 Web 移植版,基于 Spring Boot 3.3、Thymeleaf、Bootstrap 5.3 与 MySQL 8.0 构建。它面向翻译写作提供资料、词汇、句库、文本工具、对照制作、查找、备份恢复及旧库迁移等功能,完整继承桌面版核心业务规则,支持一键启动与离线访问。

howard2005的专栏 147

V8 机制、手写核心函数与 TypeScript 类型体操

或固定初始化(如数组先定长、对象先给全字段)保持类型与形状稳定;这些都比"换框架"更基础。只能处理纯数据(丢函数、Date、RegExp、循环引用报错)。生产级深拷贝要处理:原始值短路、循环引用、V8(Chrome / Node 的 JS 引擎)不是"解释一行跑一行"那么简单,它用。图:V8 执行流程——解释执行 + 热点优化,优化失败会 Deopt 回退。JS 内存自动管理,但"自动"不等于"不会漏"。是"固定间隔最多执行一次"。手写 Promise 是"懂异步"的试金石。是"停下后才执行最后一次",

qq_38468358的博客 350

副队长BootStrap5探究(2)--按钮与按钮组

本文系统讲解Bootstrap 5按钮组件的使用与底层原理。通过CDN引入框架,掌握btn基础类及primary、success等主题色应用,学习轮廓按钮(btn-outline-*)、尺寸控制(btn-lg/sm)、块级布局(d-block)和禁用状态(disabled)等实用功能。结合源码解析,深入理解其基于CSS的圆角、过渡动画、伪类交互实现机制,实现“快速上手+原理掌握”的双重目标,助力前端技能进阶。

编程副队长 672

DSH (DeepSeek Harness) Windows 升级安装指南20261107

注意:如果在普通窗口执行 nvm 提示找不到命令,或执行 nvm use 提示 Access is denied,请务必关闭当前窗口,重新打开一个管理员CMD 执行上述完整路径命令。找到 .credentials.yaml,将其重命名为 .credentials.yaml.bak(备份并使其失效)。Node.js Storage Location:可改到非系统盘(如 D:\dev\nvm,避免路径含空格或中文)。打开文件资源管理器,进入 C:\Users<你的用户名>.dsh\。

fengye207161的博客 215

SpringBoot「衣依」服装销售平台:144个Java文件180个接口,从挑衣服到收货评价整条链路都在

# SpringBoot「衣依」服装销售平台:144个Java文件180个接口,从挑衣服到收货评价整条链路都在 > 这是一套基于 Spring Boot 的服装销售平台源码,配套 `db.sql` 建表脚本,业务覆盖商品展示、购物车、订单流转、收货地址、订单评价、商品评论、在线客服、轮播图和资讯。形态是**前后台双端**:前台是顾客逛的商城,后台是管理员管的控制台。本文带你看清里面有什么、怎么跑

面朝大海 226

微信小程序-wxs

在微信开发者工具中右键创建.wxs后缀的文件。每个.wxs文件也是一个独立模块,同样使用导出内容。示例(文件return d;FOO: foo,bar: bar(外联定义参考官方文档)

dreams_dream的博客 350

汽车租赁系统(协同过滤算法、支付宝沙盒支付、 腾讯地图接入、WebSocket在线沟通、ECharts运营分析、三角色协同、还车费用处理)

本系统基于B/S架构,采用前后端分离设计,集成SpringBoot3、Vue2、MySQL等技术,实现用户、商家、管理员三角色协同管理。亮点包括:车型加权推荐与话题协同过滤算法提升个性化体验;支付宝沙盒支付、腾讯地图定位、WebSocket在线沟通保障流程闭环;还车费用智能计算与ECharts多维数据可视化助力运营分析,全面支持租车全生命周期管理。

paopaokaka_luck的博客 159

设计模式(unity游戏研发版)

当你使用图形用户界面类时通常会遇到一个问题。比如,你创建了自定义按钮类并允许客户端在按钮中注入自定义代码,这样当用户按下按钮时就会触发这些代码。观察者模式允许任何实现了订阅者接口的对象订阅发布者对象的事件通知。你可在按钮中添加订阅机制,允许客户端通过自定义订阅类注入自定义代码。在Unity中,这就像UnityEvent在Inspector中绑定多个回调。

m0_63330263的博客 107

【技术专题】JavaScript 网页技术 - JavaScript 流程控制

小锋老师推出《一天学会JavaScript(无废话版)》视频教程,涵盖基础语法、流程控制、函数、数组对象、DOM操作及ES6新特性。内容精炼,配套课件与源码打包下载,助力快速入门。重点讲解if/else、switch、for/while循环、for...of/in遍历及break/continue使用场景,并通过成绩判断实例演示实际应用。适合零基础学习者高效掌握核心技能。

java1234的博客 164
上一篇: 十一、排他思想、window、延时定时器、间歇函数、时间戳、location、navigator、history、本地存储localStorage
下一篇: 十三、元素尺寸与位置、节点操作(查找 增加 删除、父节点 子节点 兄弟节点)、阶段案例-智慧园区
bpmf_fff
博客等级 码龄6年 219粉丝 49原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值