看完必会的正则表达式和递归
1,递归
递归函数:一个函数在内部可以调用其本身
function func() {func()
}
func()
递归容易发生栈溢出错误(stack overflow),以上是一个典型的栈溢出,所以我们必须加退出条件 return
var num = 1
function func() {console.log(`打印${num}次`)if (num === 10) {return}num++func()
}
func()
递归实例:
- 1, 利用递归求 1 ~ n 的阶乘
function func(n) {// 1 * 2 * 3 * ...nif (n === 1) return 1;return n * func(n - 1)
}
func(5) // 120
- 2, // 斐波那契数列(兔子序列):前两项的和等于第三项的值 表现: 1、1、2、3、5、8、13、21、34…
// 用户输入一个数字 n, 求出这个数字对应的兔子序列值
function fb (n) {if (n === 1 || n === 2) return 1return fb(n - 1) + fb(n - 2)
}
fb(9) // 34
- 3, 根据 id 返回对应的数据对象
const arr = [{id: 1,name: 'Jerry',friends: [{id: 11,name: 'Lise'},{id: 12,name: 'Tom'}]},{id: 2,name: 'xiaowang'}
];const arr = [{id: 1,name: 'Jerry',friends: [{id: 11,name: 'Lise'},{id: 12,name: 'Tom'}]},{id: 2,name: 'xiaowang'}
];
function getId(data, id) {var o = {}data.forEach(function (value) {if (value.id === id) {o = valuereturn value} else if (value.friends?.length > 0) {o = getId(value.friends, id)}})return o
}
console.log(getId(arr, 12)) // {id: 12, name: 'Tom'}
或者
function getId(arr, id) {let queue = [];arr.forEach(item => {queue.push(item)})while(queue.length > 0) {const value = queue.shift();if(value.id === id) return value;if(value.friends && value.friends.length > 0) {value.friends.forEach(item => queue.push(item));}}
}
console.log(getId(arr, 12)) // {id: 12, name: 'Tom'}
2,深浅拷贝
- 1,浅拷贝只是拷贝一层,更深层对象级别的只拷贝引用
- 2,深拷贝拷贝多层,每一级别的数据都会拷贝
浅拷贝
const obj = {name: 'Jerry',age: 18,friends: {name: 'Lise'}
};
var o = {}for (var i in obj) { // i 属性名,obj[i] 属性值o[i] = obj[i]
}
或
Object.assign(o, obj) // ES6新增的方法可以实现浅拷贝o.friends.name = 'Tom'
console.log(o)
console.log(obj)
深拷贝
const obj = {name: 'Jerry',age: 18,friends: {name: 'Lise'},colors: ['red', 'green', 'blue']
};
var o = {}
// 封装函数
function deepCopy(newObj, oldObj) {for(var i in oldObj) {// 判断属性值是简单数据类型还是复杂数据类型// 1,获取属性值 oldObj[i]const item = oldObj[i]// 2, 判断这个值是否是数组if (item instanceof Array) {newObj[i] = []deepCopy(newObj[i], item)} else if (item instanceof Object) {// 3,判断这个值是否是对象newObj[i] = {}deepCopy(newObj[i], item)} else {// 4,属于基本数据类型newObj[i] = item}}
}
deepCopy(o, obj)
3,正则表达式
正则表达式:用于匹配字符串中字符组合的模式,在JS中,正则表达式也是对象。
通常用于检测、替换那些符合某个模式的文本,例如验证表单:用户名表单只能输入英文字母、数字或者下划线。
还常用于过滤页面内容中的一些敏感词(替换),或者从字符串中获取我们想要的特定部分等
3.1,创建正则表达式
- 创建正则表达式:
- 1, 利用
RegExp
对象来创建
const rg = new RegExp(/表达式/)
- 2, 利用字面量创建正则表达式
const rg = /表达式/
- 1, 利用
- 测试正则表达式
test
test()正则对象的方法,用于检测字符串是否符合该规范,该对象会返回true
或false
const rg = /123/
rg.test(123) // true
rg.test(456) // false
- 正则的组成
一个正则可以由简单的字符组成,比如/abc/,也可以是简单和特殊字符的组合,比如/ab*c/,特殊字符有叫元字符,在正则中具有特殊意义的专用符号,比如: ^、$、+等
特殊符号可以参考:MDN正则表达式
正则测试工具:https://tool.oschina.net/regex
3.2,正则中的特殊字符
- 3.2.1 边界符
正则中的边界符(位置符)用来提示字符串所处的位置,主要有两个:^、$- ^ 匹配行首的文本
- $ 匹配行尾的文本
const rg = /abc/ // /abc/表示只要包含有abc这个字符串返回的都是true
console.log(rg.test('abc')) // true
console.log(rg.test('abcd')) // true
console.log(rg.test('aabc')) // trueconst reg = /^abc/ // 表示必须以abc开头的
console.log(reg.test('abc')) // true
console.log(reg.test('abcd')) // true
console.log(reg.test('aabc')) // false
console.log(reg.test('abdc')) // falseconst reg1 = /^abc$/ // 精确匹配
console.log(reg1.test('abc')) // true
console.log(reg1.test('abcd')) // false
console.log(reg1.test('aabc')) // false
- 3.2.2 字符类:[]
表示有一系列字符可供选择,只要匹配其中一个就可以了
const reg = /[abc]/ // 表示只要包含有a 或 有b 或 有c,都返回true
console.log(reg.test('alia')) // trueconst reg1 = /^[abc]$/ // 表示只有是a 或 b 或 c,才返回true
console.log(reg1.test('alia')) // false
console.log(reg1.test('a')) // true
console.log(reg1.test('b')) // true
console.log(reg1.test('bc')) // false
console.log(reg1.test('c')) // true
console.log(reg1.test('cc')) // false
console.log(reg1.test('abc')) // false
- 3.3.3 [-]方括号内 范围符 -
const reg = /^[a-z]$/ // 26个英文字母任何一个字母返回true
console.log(reg.test('alia')) // false
console.log(reg.test('a')) // true
console.log(reg.test('A')) // false
- 3.3.4 字符组合
// 字符组合
const reg1 = /^[a-zA-Z]$/ // // 26个英文字母(大小写都可以) 任何 一个字母返回true
console.log(reg1.test('alia')) // false
console.log(reg1.test('a')) // true
console.log(reg1.test('A')) // true// 比如:reg = /^[a-zA-Z0-9_-]$/
- 3.4.5 []方括号内 表示取反
const reg = /^[^abc]$/
console.log(reg.test('a')) // false
- 3.4.6 量词符
用来设定某个模式出现的次数
量词 | 说明 |
---|---|
* | 重复0次或更多次 |
+ | 重复1次或更多次 |
? | 重复0次或1次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
// * >= 0
const reg = /^a*$/
console.log(reg.test('')) // true
console.log(reg.test('a')) // true
console.log(reg.test('b')) // false
console.log(reg.test('aaa')) // true// + >= 1
const reg1 = /^a+$/
console.log(reg1.test('')) // false
console.log(reg1.test('a')) // true
console.log(reg1.test('b')) // false
console.log(reg1.test('aaa')) // true// ? 1 || 0
const reg2 = /^a?$/
console.log(reg2.test('')) // true
console.log(reg2.test('a')) // true
console.log(reg2.test('b')) // false
console.log(reg2.test('aaa')) // false// {3} 重复3次
const reg3 = /^a{3}$/
console.log(reg3.test('')) // false
console.log(reg3.test('a')) // false
console.log(reg3.test('b')) // false
console.log(reg3.test('aaa')) // true// {3,} >= 3
const reg4 = /^a{3,}$/
console.log(reg4.test('')) // false
console.log(reg4.test('a')) // false
console.log(reg4.test('b')) // false
console.log(reg4.test('aaa')) // true
console.log(reg4.test('aaaaa')) // true
console.log(reg4.test('aaabc')) // false
console.log('-----------')
// {3,8} >= 3 && <= 8
const reg5 = /^a{3,8}$/
console.log(reg5.test('')) // false
console.log(reg5.test('a')) // false
console.log(reg5.test('b')) // false
console.log(reg5.test('aaa')) // true
console.log(reg5.test('aaaaa')) // true
console.log(reg5.test('aaabc')) // false
console.log(reg5.test('aaaaaaaa')) // true
- 3.4.7
// 量词是设定某个模式出现的次数
var reg = /^[a-zA-Z0-9_-]$/ // 这个模式用户只能输入英文字母 数字 下划线 短横线但是有边界符和[] 这就限定了只能多选1
console.log(reg.test('a')) // true
console.log(reg.test('ab')) // false
console.log(reg.test(1)) // true
console.log(reg.test('11')) // false
console.log(reg.test('aa')) // false
4, 正则案例
1, 用户名验证,如果用户名输入合法,提示信息为:用户名合法,颜色改为绿色,如果不合法,则后面提示:用户名不符合规范,改色改为红色
const name = document.querySelector('.name');
const span = document.querySelector('span');
var reg = /^[a-zA-Z0-9_-]{6,16}$/
name.onblur = function () {if (reg.test(this.value)) {span.className = 'green'span.innerHTML = '用户名合法'} else {span.className = 'red'span.innerHTML = '用户名不符合规范'}
}
5, 括号总结
- 1,量词符大括号,表示重复次数
- 2,字符集合中括号,匹配方括号中的任意字符
- 3,小括号,表示优先级
// 中括号[],字符集合,匹配方括号中的任意字符
const reg = /^[abc]$/ // a || b || c都可以// 大括号{},量词符,表示重复次数
const reg1 = /^[abc]{3}$/
console.log(reg1.test('aaa')) // true
console.log(reg1.test('abcabcabc')) // falseconst reg2 = /^abc{3}$/ // 它只是让c重复3次 abccc
console.log(reg2.test('aaa')) // false
console.log(reg2.test('abcabcabc')) // false
console.log(reg2.test('bbb')) // false
console.log(reg2.test('ccc')) // false
console.log(reg2.test('abccc')) // true
console.log(reg2.test('aabccc')) // false// 小括号 表示优先级
const reg3 = /^(abc){3}$/ // 表示让 abc重复3次
console.log(reg3.test('aaa')) // false
console.log(reg3.test('abcabcabc')) // true
console.log(reg3.test('abccc')) // false
6,可以在线测试自己写的正则对不对(https://c.runoob.com/front-end/854/)
7,预定义类
指的是某些常见模式的简写方式
预定义类 | 说明 |
---|---|
\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] |
实例:
// 座机号码验证:全国座机号码,两种格式:010-12345678 或者 0530-1234567
// const reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/ // 正则里的 或 用 | 表示
// 简写
const reg = /^\d{3,4}-\d{7,8}$/
console.log(reg.test('魑魅魍魉')) // false
console.log(reg.test('3829889')) // false
console.log(reg.test('3829-889')) // false
console.log(reg.test('022-31231321')) // true
8, replace 替换
replace()方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则
// 语法
str.replace(/str/, replacement)
// 第一个参数:被替换的字符串 或者 正则
// 第二个参数:替换为的字符串
// 返回值是一个替换完的新字符串
const str = 'JerryLise'
const newStr = str.replace('Jerry', 'xiaowang')
const newStr = str.replace(/Jerry/, 'xiaowang')
console.log(newStr) // xiaowangLise
实例:
const text = document.querySelector('textarea')
const btn = document.querySelector('button')
const div = document.querySelector('div')
btn.onclick = function () {div.innerHTML = text.value.replace(/小猫咪/, '**')
}
以上代码replace只能替换第一个满足条件的字符串,后面的就不再替换了,那么我们可以用正则表达式参数
9,正则表达式参数
/表达式/[switch]
// switch也称修饰符,按照什么样的模式来匹配,有三种值:
// 1,g: 全局匹配
// 2,i:忽略大小写
// 3,gi:全局匹配 + 忽略大小写
以上实例:
div.innerHTML = text.value.replace(/小猫咪|超/g, '**')
看完必会的正则表达式和递归相关推荐
- 平安京s9服务器维护,平安京S9的细节改动,看完必上分
原标题:平安京S9的细节改动,看完必上分 就在前几天,决战平安京迎来了S9赛季,同时也迎来了巨大的改动.下面就由小编来带领大家解读S9. 首先,是我们的经济和经验来源兵线和野怪的改动,野怪血量增加了, ...
- 00018计算机应用基础怎样过,自学考试公共课00018计算机应用基础(看完必过).doc...
Page PAGE1 of NUMPAGES34. 自考公共课00018 计算机应用基础(看完必过) 计算机应用基础精髓总结 第1章计算机基础知识 1.计算机的发展和应用[选择](06年下1)计算机发 ...
- 自考计算机基础00018难吗,自考公共课00018-计算机应用基础(看完必过).doc
自考公共课00018 计算机使用基础(看完必过) 计算机使用基础精髓总结 第1章计算机基础知识 1.计算机的发展和使用[选择](06年下1)计算机发展阶段是按照计算机硬件来划分的,大致可分为四个阶段: ...
- java递归看回文,如何使用正则表达式实现递归回文检查器? [关闭]
如果我理解正确,你想在Java中创建一个使用正则表达式的递归回文检查器 . 我对学习Java感兴趣,所以我把它作为我自己的"家庭作业问题",但它也可能是你的 . import ja ...
- keil5的安装详解(看完必会,不会你打我)
如何安装KEIL5 本内容所涉及的软件只供教学使用,不得用于商业用途.个人或公司因商业用途导致的法律责任,后果自负. 温馨提示 1.安装路径不能带中文,必须是英文路径 2.安装目录不能跟51的KEIL ...
- 14年的面试官经验分享,看完必有收获
面试,是找到好工作的过程中,最最重要的一环. 在我14年的职业生涯中,亲自面试的人应该不下1000人了. 看过的简历还要更多,尤其是微软上海早期扩张的时候. 所以今天,我就从自身经历出发,给你分享一些 ...
- MOS管的工作原理及常见的封装(看完必会)
MOS管的工作原理及常见的封装目录 MOS管的概述 MOS管的性能 MOS管的管脚及常见封装识别 MOS管的导通条件 加强理解MOS管 Question? 致谢 MOS管的概述 场效应管(FET),把 ...
- java开发小程序好吗,看完必懂
1关于MySQL,面试官会问哪些问题? 第一个:MySQ性能优化最佳实践21个(有具体的解释)你知道哪些? 为查询缓存优化你的查询 EXPLAIN你的SELECT查询 当只要一行数据时使用LIMIT ...
- pythone二级题库 + 刷题软件 (超详细解析,看完必过) 第十一套
刷题软件(模拟python二级考试) 操作题刷题软件 1.计算机完成一条指令所花费的时间称为一个(). A.指令周期 B.存取周期 C.执行速度 D.执行时序 一般把计算机完成一条指令所花费的时间统称 ...
- 电商零售业怎么做数据分析?这10篇作品看完必会
在2021帆软BI可视化夏季挑战赛中,我们看到了非常多的优秀BI可视化分析作品.其中,零售/电商类的作品尤为丰富,今天帆软君为大家精选出10份优秀作品,希望能够给零售/电商的朋友们带来一些启发: 1. ...
最新文章
- glusterfs4.0.1 mempool 分析笔记
- 南京人工智能高等研究院孔慧:多向技术驱动,让企业具备长久竞争力
- redis(9)--数据库
- 【git学习】统计git项目某user的代码量
- 中国半导体蚀刻设备行业市场供需与战略研究报告
- java.io.IOException: CreateProcess error=2, ?????????
- ant 使用java 运行类_用ANT构建java可执行程序
- linux远程配置ssh服务,Linux远程服务之OpenSSH配置
- [笔记]C++代码演示SingletonMap 单类Map实例
- 幼儿-综合素质【1】
- office 论文 页码_毕业论文页码格式word操作
- 【双轨公排】小公排+推荐奖+对碰奖+层碰奖+见点奖源码系统 演示网站介绍
- 手把手带你Yolov5 (v6.x)添加注意力机制(一)(并附上30多种顶会Attention原理图)(新增8种)
- 相濡以沫,不如相忘于江湖...
- 消失的网秦:创始人遭绑架 414 天,睡觉都戴手铐
- resultful风格接口
- 区块链报错3 | truffle unbox 报错 | downloading失败 | unbox failed
- 2021年塔式起重机司机考试及塔式起重机司机复审考试
- 分享高压超低噪声LDO测试结果(High Voltage Ultra-low Noise LDO)
- Python版经典小游戏愤怒的小鸟源代码,基于pygame+pymunk
热门文章
- Radiology:磁共振血管造影(MRA)在脑转移瘤治疗中对血管形态改变的测量
- 风口下的追逐:AI正在驾驶、客服、教育领域疾驰
- mysql数据库安全开关_对MySQL数据库的安全进行的详述
- 学硕上几年学计算机,研究生一般要读几年毕业
- android数据格式化,手机格式化了?教你找回安卓手机数据
- 台风怎么看内存颗粒_《CY》又一4000+的颗粒,三星新版D-DIE颗粒超频测试
- Linux系统 查看 Vendor id 和Device id
- Android多分辨率适配框架(1)— 核心基础
- 锐龙r75800u参数 r7 5800u怎么样
- unixbench跑服务器性能,UnixBench 5.1.3性能测试_IntelCPU_服务器评测与技术-中关村在线...