360前端星——0410笔记

279 阅读7分钟

正则的三个应用场景

创建正则表达式

使用正则表达式字面量

const reg = /[a-z]\d + [a-z]/i

  • 优点
    • 简单方便
    • 不需要考虑二次转义
  • 缺点
    • 子内容无法重复使用
    • 过长的正则导致可读性差

使用RegExp构造函数

const alphabet = '[a-z]'
const reg = new RegExp('${alphabet}\\d+${alphabet}', 'i')
  • 优点
    • 子内容可以重复使用
    • 可以通过控制子内容的粒度提高可读性
  • 缺点
    • 二次转义的问题非常容易导致bug

正则表达式的常见用法

RegExp.prototype.test()

const reg = /[a-z]\d+[a-z]/i

reg.text('a1a') //true
reg.text('1a1') //false
  • 输入:输入字符串,如果不是就进行类型转换,失败抛出TypeError
  • 输出:true / false

RegExp.prototype.sourceRegExp.prototype.flags

  • source 指向正则表达式中间的部分,即模式文本的字符串
  • flags 返回修饰符的字符串

RegExp.prototype.exec()RegExp.prototype.match()

  • exec() 输入字符串
  • match() 输入正则表达式
  • 当表达式含有 g 修饰符时,exec() 每次只返回一个匹配结果,数据格式和不含 g 的相同。match() 会返回所有匹配结果,数据格式会变为字符串数组
  • 建议使用exec()

RegExp.prototype.lastIndex

  • 表示最后一次匹配成功的位置,即下一次匹配开始的位置
  • 不会自己重置,只有上一次匹配失败才会重置为0

其他常见用法举例

'a1a'.replace(/a/, 'b') // 替换
'a1a'.replace(/a/g, 'b')

'a1a'.search(/a/) // 搜索出现的位置
'a1a'.search(/a/g)

'a1a'.split(/a/)
'a1a'.split(/a/g)

//b1a
//b1b
//0
//0
//[ '', '1', '' ]
//[ '', '1', '' ]

正则与数值

^匹配一个输入或一行的开头/^a/匹配"an A",而不匹配"An a" $匹配一个输入或一行的结尾/a$/匹配"An a",而不匹配"an A"

*匹配前面元字符0次或多次,/ba*/将匹配b,ba,baa,baaa

+匹配前面元字符1次或多次,/ba*/将匹配ba,baa,baaa ?匹配前面元字符0次或1次,/ba*/将匹配b,ba (x) 匹配x保存x在名为$1...$9的变量中 x|y匹配x或y {n}精确匹配n次 {n,} 匹配n次以上 {n,m} 匹配n-m次 [xyz] 字符集(character set),匹配这个集合中的任一一个字符(或元字符) [^xyz] 不匹配这个集合中的任何一个字符 [\b]匹配一个退格符 \b 匹配一个单词的边界 \B 匹配一个单词的非边界 \cX 这儿,X是一个控制符,/\cM/匹配Ctrl-M \d 匹配一个字数字符,/\d/ = /[0-9]/ \D 匹配一个非字数字符,/\D/ = /[^0-9]/ \n 匹配一个换行符 \r 匹配一个回车符 \s 匹配一个空白字符,包括\n,\r,\f,\t,\v\S 匹配一个非空白字符,等于/[^\n\f\r\t\v]/ \t 匹配一个制表符 \v 匹配一个重直制表符 \w 匹配一个可以组成单词的字符

数值判断优化示例:

  • /[0-9]+/
    • 不是全字符匹配
    • 连字符要挨着方括号防止
  • /^\d+$/
    • 不能匹配带符号的数、小数
  • /^[+-]?\d+(\.\d+)?$/
    • 不能匹配无整数形式的小数
    • 捕获组会带来额外的开销
  • /^[+-]?(?:\d*\.)?\d+$/
    • 不能匹配无小数的数值2.
    • 不能匹配科学计数法1e2

完整的数值正则

/^[+-]?(?:\d+\.?|\d*\.\d+)(?:e[+-]?\d+)?$/i

用正则处理数值

  • 数值的解析
    • ?=expression 先行断言,用于匹配符合条件的位置

正则表达式的先行断言和后行断言一共有4种形式: (?=pattern) 零宽正向先行断言(zero-width positive lookahead assertion) (?!pattern) 零宽负向先行断言(zero-width negative lookahead assertion) (?<=pattern) 零宽正向后行断言(zero-width positive lookbehind assertion) (?<!pattern) 零宽负向后行断言(zero-width negative lookbehind assertion) 这里面的pattern是一个正则表达式。

如同^代表开头,$代表结尾,\b代表单词边界一样,先行断言和后行断言也有类似的作用,它们只匹配某些位置,在匹配过程中,不占用字符,所以被称为“零宽”。所谓位置,是指字符串中(每行)第一个字符的左边、最后一个字符的右边以及相邻字符的中间(假设文字方向是头左尾右)。

  • 数值转货币格式

    • $n用于replace字符串时,表示第n个捕获组

      const reg = /(\d)(?=(?:\d{3})+(?:,|$))/g
      

正则与颜色

颜色的表示方式

  • 16进制表示法
    • #rgb#rgba
    • 正则写法
      • const hex = '[0-9a-fA-F]'
      • '^(?:#${hex}{6}|#${hex}{8}|#${hex}{3,4})$'
  • rgb/rgba表示法
    • 取值可以用百分比
    • 取值应该是0~255的整数,但是溢出或小数不会报错

使用正则处理颜色

  • 16进制颜色的优化
    • 6、8位两两相等的情况可以省略一半
    • (?<key>)
      • 具名捕获组,给捕获组命名
      • 反向引用\k<key>
      • replace中,使用$<key>来访问
      • 应用exec时,使用execResult.groups[key]访问

正则与URL

用正则解析URL

完整的URL规范

  • schema:
    • 可选://
      • 可选:userinfo@
    • host
      • 可选::port
  • path
    • 可选:?query
    • 可选:#fragment

用正则解析search和hash

  • 先忽略前导的# ?

    • str.replace(/^[#?&]/,'')
    • ?后是key=value
  • 解析剩下的部分

    • const reg = /(?:^|&)([^&=]*)=?([^&]*?)(?=&|$)/y
    • *? 非贪婪,只匹配第一个符合条件的结果
    • y 粘连修饰符,全局匹配
      • 结果必须是连续的
      • 在match时只返回第一个匹配结果
  • 防止匹配到空字符串时的死循环

    if(!str) {
        return result
    }
    

课后作业

function getUrlParam(str, key) {
    
}
console.log(getUrlParam('?nothing', 'test')) // ''
console.log(getUrlParam('#a=1&aa=2&aaa=3', 'a')) // ''
console.log(getUrlParam('&b=1&a=1&b=2', 'b')) // ''
console.log(getUrlParam('a=1&b=2&c=&d', 'c')) // ''
console.log(getUrlParam('&d==', 'd')) // ''

总结

  • 明确需求
  • 考虑全面
    • 极端的情况
  • 反复测试

Node.js 基础入门

什么是Node.js

  • 与JavaScript的区别
    • 基于异步I/O相关结构
      • 读写文件、网络请求
    • 基于node_modules 、require的模块依赖
    • 提供C++ addon API与系统交互
  • 用处
    • Web服务端
    • cli 命令行脚本
    • GUI 客户端软件
    • 图像处理、IoT等

Node.js基础

  • 内置模块:如 http fs等
  • 文件模块
    • require文件即可调用暴露的方法exports
  • 模块加载:绝对路径、相对路径、无后缀文件、外部模块
  • 模块路径查找
    • 绝对路径、相对路径直接查找,相对转化为绝对
    • 模块/文件夹
      • 原生模块直接读取缓存
      • 依次往上查找node_modules
      • 解析package.json,查找main属性,没有则使用index.js
      • 未找到会报错
  • 模块缓存:节省后续的I/O操作

NPM——包管理器

  • package.json文件是必须的,存放于包顶级目录下。包含了规范、包版本号、依赖等
  • 示例:
    • scripts:常用脚本的快捷执行方式
    • dependencies:被别人安装的时候需要使用的
    • devDependencies:仅在开发的时候需要用到的
    • version:版本号

软件版本号分3段,比如 A.B.C A 表示大版本号,一般当软件整体重写,或出现不向后兼容的改变时,增加A,A为零时表示软件还在开发阶段。 B 表示功能更新,出现新功能时增加B C 表示小修改,如修复bug,只要有修改就增加C

除了版本号之外还会有一些修饰的词,比如: alpha: 内部版本 beta: 测试版 rc: 即将作为正式版发布 lts: 长期维护

{
  "name": "12345",
  "description": "A Vue.js project",
  "version": "1.0.0",
  "author": "",
  "license": "MIT",
  "private": true,
  "scripts": { 
    "dev": "cross-env NODE_ENV=development webpack-dev-server --host 0.0.0.0 --open --hot",
    "build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
  },
  "dependencies": {
    "axios": "^0.19.2",
    "babel-polyfill": "^6.26.0",
    "better-scroll": "^1.15.2",
    "fastclick": "^1.0.6",
    "stylus": "^0.54.7",
    "stylus-loader": "^3.0.2",
    "vue": "^2.5.11",
    "vue-awesome-swiper": "^2.6.7",
    "vue-router": "^3.1.6",
    "vuex": "^3.1.2"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ],
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.0",
    "babel-preset-stage-3": "^6.24.1",
    "cross-env": "^5.0.5",
    "css-loader": "^0.28.7",
    "file-loader": "^1.1.4",
    "vue-loader": "^13.0.5",
    "vue-template-compiler": "^2.4.4",
    "webpack": "^3.6.0",
    "webpack-dev-server": "^2.9.1"
  }
}
  • 包依赖
  • version Must match version exactly
  • >version Must be greater than version
  • >=version etc
  • <=version
  • ~version “Approximately equivalent to version” See semver
  • ^version “Compatible with version” See semver
  • 1.2.x 1.2.0, 1.2.1, etc., but not 1.3.0
  • * Matches any version
  • "" (just an empty string) Same as *
  • version1 - version2 Same as >=version1 <=version2.

基于Node.js的Web开发

  • Koa
    • 基于Node.js的web框架
    • 无规范约束,不利于团队开发,中间件繁多
    • 企业级框架需要规范约束
  • thinkJS
    • 目录结构的规范在各个项目中是一致的

TODO list项目实战

  • 功能列表
    • 页面
    • API
      • 获取todo列表
      • 增加、删除、更新todo
  • 数据表设计
  • thinkjs 创建项目
  • 启动项目
  • 将模板文件进行修改,完成页面
  • RESTful API开发
    • 每个API都对应一种资源或资源集合
    • 用http 方法表示对资源的动作
    • 最后用状态码返回资源操作的结果

Rest架构的主要原则

  • 网络上的所有事物都被抽象为资源

  • 每个资源都有一个唯一的资源标识符

  • 同一个资源具有多种表现形式(xml,json等)

  • 对资源的各种操作不会改变资源标识符

  • 所有的操作都是无状态的

  • 符合REST原则的架构方式即可称为RESTful

Restful web service是一种常见的rest的应用,是遵守了rest风格的web服务;rest式的web服务是一种ROA(The Resource-Oriented Architecture)(面向资源的架构).

  • 在基类中实现增删改查
  • 配置数据库
    • 数据库操作方法、基本配置
  • 数据校验
    • 在logic层之上
    • 对用户数据、权限进行校验,专门用这层进行处理

Node.js的调试

  • 日志调试

    • console.log
  • 断点调试

    • node --inspect
    • vscode
      • F5
    • ndb
      • chrome中的,可以接在任意的node命令前面
  • 摆好心态,多了解服务端的知识。