正则的三个应用场景
创建正则表达式
使用正则表达式字面量
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.source和RegExp.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与系统交互
- 基于异步I/O相关结构
- 用处
- Web服务端
- cli 命令行脚本
- GUI 客户端软件
- 图像处理、IoT等
Node.js基础
- 内置模块:如 http fs等
- 文件模块
- require文件即可调用暴露的方法
exports
- require文件即可调用暴露的方法
- 模块加载:绝对路径、相对路径、无后缀文件、外部模块
- 模块路径查找
- 绝对路径、相对路径直接查找,相对转化为绝对
- 模块/文件夹
- 原生模块直接读取缓存
- 依次往上查找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"
}
}
- 包依赖
versionMust match version exactly>versionMust be greater than version>=versionetc<=version~version“Approximately equivalent to version” See semver^version“Compatible with version” See semver1.2.x1.2.0,1.2.1, etc., but not 1.3.0*Matches any version""(just an empty string) Same as *version1 - version2Same 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命令前面
-
摆好心态,多了解服务端的知识。