01-正则表达式
中立于语言和平台的 一种描述字符规则的 特殊表达式
ECMAScript 定义了 内置对象 RegExp(正则表达式对象)
在ES中 属于引用数据类型
正则表达式 使用普通字符 和 特殊字符构成
主要的用途: 格式验证 匹配文本 内容查找 文本替换 …
正则表达式创建
1. 使用构造函数创建
let reg = new RegExp(string[,prop]);
参数: string 用于描述字符信息(字符规则)的字符串
prop 正则表达式修饰符
ignorecase 忽略大小写
global 全局
/ let reg = new RegExp(‘abc’);
console.log(reg);
console.log(typeof reg);
2. 字面量创建
let reg = /string/prop;
let reg2 = /abc/;
console.log(reg2);
console.log(reg2 === reg);
在正则表达式中 有一些特殊字符 无法直接进行字符描述 需要转义后进行描述
转义符 \
特殊字符 . / \ + ? * ( ) [ ] { } ^ | $
转义写法 . \$
—————————————————————————
RegExp.prototype.test()
语法: reg.test(string)<br /> 参数: string 需要验证规则的字符串<br /> 返回值: boolean<br /> 描述: test 方法 将使用正则表达式 验证 字符串是否符合正则所描述的规则 并返回一个布尔值
02-字符集
在正则表达式中 使用 [] 表示<br /> 每一个字符集表示需要匹配括号中的 任意一个字符<br /> ^ 出现在字符集的开始位置 含义 非 <br /> 在正则表达式中 字符集里出现了 - <br /> 表示匹配范围 默认匹配askii编码<br /> 65-90 大写字母范围<br /> 97-122 小写字母范围<br /> A-z 65-122<br /> 91-96范围 [ ] \ _ ^ `<br /> [abc] 匹配abc中的任意一个字符<br /> [abc][ac] 匹配两个字符 第一个字符是abc中任意一个 第二个字符是ac中任意一个<br /> [^abc] 匹配一个字符 非abc中任意字符<br /> [0-9] 匹配一个数字<br /> [a-z] 匹配一个小写字母<br /> [A-Z] 匹配一个大写字母<br /> [A-Za-z] 匹配大小写字母 /[a-z]/i /[A-Z]/i<br /> [A-z] 匹配askii编码范围<br /> [A-Za-z0-9_] 匹配 字母、数字、下划线
03-预定义字符串
预先设置好的字符集简写
\d 匹配一个数字 等同于 [0-9]
\D 匹配一个非数字 等同于 [^0-9]
\w 匹配字母、数字、下划线 等同于 [A-Za-z0-9]
\W 匹配非字母、数字、下划线 等同于 [^A-Za-z0-9]
\s 匹配一个 空格
\S 匹配一个 非空格
. 匹配除换行外的任意字符
04-匹配数量
匹配数量
字符出现的频次
n? 表示字符出现0次或1次
n+ 表示字符出现1次或多次
n* 表示字符出现0次或多次
n{x} 表示字符出现x次
n{x,y} 表示字符出现x至y次
n{x,} 表示字符出现至少x次
05-匹配边界
const reg = /^(+86)?1[3-9]\d{9}$/;
匹配边界
^ 开始边界
$ 结束边界
06-选择分组
https:regexper.com/
const userinput = document.querySelector(‘#userinput’);
const message = document.querySelector(‘#message’);
const reg = /^A-Z|(123))$/;
选择分组
() 表示分组 一个圆括号内的内容 被看作是一个整体
| 表示选择 类似于 逻辑或
验证身份证号格式
18位
12表示省份
34城市
56区县
7-14 生日
15-17 顺序号
17 表示性别
18 校验码
正则表达式没有计算能力 无法识别最后校验码是否正确
正则表达式有验证格式的能力
生日格式
年份以 19 或 20开头的年份 1900-2099
月 01-12
日 01-31
07-字符串API
String.prototype.match()
语法: str.match(regexp)
描述: match函数通过正则表达式 在字符串中匹配内容 将匹配到的结果存入一个新数组
返回值: array
找到所有单词
单词边界 \b
let str1 = ‘A boy can do every for girl.’;
const arr = str1.match(/[a-z]+\b/ig);
console.log(arr);
let str2 = ‘hell你好o w世orl界d’;
找到所有汉字
[\u4e00-\u9fa5] 汉字的Unicode范围
const arr2 = str2.match(/[\u4e00-\u9fa5]+/g);
console.log(arr2);
let str3 = ‘3he5ll765o3’;
const arr3 = str3.match(/\d+/g);
console.log(arr3);
——————————————————————————————————
String.prototype.search()
语法: str.search(regexp);<br /> 描述: 在字符串中 通过正则表达式 检索匹配文本内容 返回第一个匹配到的结果文本的索引<br /> 返回值: 索引 或 -1<br /> indexOf 正则版<br /> let str = '1234b56';<br /> console.log(str.search(/[a-z]/));<br /> ---------------------------------------------------------------------
String.prototype.replace()
语法: str.replace(regexp,string);<br /> 参数: regexp 描述文本规则的表达式<br /> string 使用新的字符串片段替换正则所匹配的文本<br /> 返回值:string 新字符串<br /> let str = 'hgjk23lds56h32jk23h2l1aa';<br /> 删除所有数字<br /> let str2 = str.replace(/\d/g, '');<br /> console.log(str2);<br /> () 表示分组<br /> 每一个分组 都有一个分组编号 分组编号从1开始<br /> 在使用replace进行替换操作时 可以使用分组编号表示匹配的内容<br /> 第一个分组 使用 $1 表示<br /> 第二个分组 使用 $2 表示<br /> ....<br /> 分组的编号是按照左括号的开始进行计算的<br /> let str3 = '123abc';<br /> let str4 = str3.replace(/(\d+)([a-z]+)/, '$2$1');<br /> console.log(str4);<br /> let str5 = '1234567890';<br /> let str6 = str5.replace(/(\d{2})((\d{3})(\d+))/, '$2$4$1$3'); 34567890 67890 12 345<br /> console.log(str6);<br /> console.log(RegExp.$1);<br /> console.log(RegExp.$2);<br /> console.log(RegExp.$3);<br /> console.log(RegExp.$4);<br /> ---------------------------------------------<br /> 应用:<br /> 编写一个函数 统计字符长度<br /> 判断 单字节字符<br /> 双字节字符<br /> \x 16进制<br /> [\x00-\xff] 匹配单字节字符<br /> [^\x00-\xff] 匹配双字节字符
08-限定词屏蔽
词组
const words = [‘cnm’, ‘qnmlgb’, ‘sb’, ‘中国共产党’, ‘习大大’];
词组转正则
let word = words.join(‘|’);
let reg = new RegExp(word, ‘ig’);
submit.onclick = function () {
text.value = text.value.replace(reg, ‘**’);
}
09-了解XXS
XSS 跨站脚本攻击
跨站脚本攻击 通常使用恶意的JavaScript代码获得用户的会话信息或登录信息 进行破坏等操作…
前端工程师 需要规避 XSS 风险
XSS的重灾区 innerHTML
innerHTML 可以识别并执行代码 需要让用户输入的内容没有可执行的元素或代码 这样才是安全的
提交前干预
1. 替换 替换调关键符号(破坏标签)
2. 转义 将可执行的内容转换成不可执行的内容
转换成 <h1>
window.onload = function () {
let text = document.querySelector(‘#text’);
let btn = document.querySelector(‘#btn’);
let output = document.querySelector(‘#output’);
btn.onclick = function () {
output.innerHTML = text.value;
output.innerHTML = text.value.replace(/<[^<>]+>/g, ‘’); 删除标签
let res = text.value.replace(/ res = res.replace(/>/g, ‘>’);
output.innerHTML = res;
}
}
10-断言
https:developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions/Assertions
断言的组成之一是边界。对于文本、词或模式,边界可以用来表明它们的起始或终止部分(如向前断言,向后断言以及条件表达式)。
() 捕获分组
let reg = /(((a)b)(c))/;
let str = ‘abc’;
console.log(reg.test(str));
console.log(RegExp.$1);
console.log(RegExp.$2);
console.log(RegExp.$3);
console.log(RegExp.$4);
console.log(str.match(reg)); match 可以获得到 分组所数据
—————————————————————-
x(?=y) 向前断言: x 被 y 所跟随 匹配x
非捕获分组匹配
let reg = /Java(?=Script)/; 匹配Java 必须紧跟Script
let str = ‘I like JavaScript’;
console.log(reg.test(str));
console.log(str.match(reg));
console.log(RegExp.$1);
——————————————————————-
x(?!y) 向前否定断言 x 没有被 y 紧随时匹配 x。
非捕获分组匹配
let reg2 = /Windows (?!10|11)/;
let str2 = ‘我使用的操作系统是 Windows 7’;
console.log(reg2.test(str2));
console.log(str2.match(reg2));
——————————————————————-
(?:x) 匹配x 但不记录匹配值
非捕获分组匹配
let reg3 = /(?:123)/;
let str3 = ‘aa123a’;
console.log(reg3.test(str3));
console.log(str3.match(reg3));
console.log(RegExp.$1);
/^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/
11-思考题
编写一个函数 传入一个整数 将这个整数进行格式化处理
例如: 输入 1234567 输出 1,234,567
输入 12345678 输出 12,345,678
function formatNum(num) {
return num.toString().replace(/(?!^)(?=(?:\d{3})+(?!\d))/g, ‘,’);
}
console.log(formatNum(1234567));
console.log(formatNum(12345678));
console.log(formatNum(123456789));
12-exec
RegExp.prototype.exec()
let reg = /[a-z]+\b/ig;
let str = ‘i liek JavaScript’;
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
console.log(reg.exec(str));
let res;
let result = [];
while (res = reg.exec(str)) {
result.push(res[0]);
}
console.log(result);
console.log(str.match(reg));
13-密码强度验证
const password = document.querySelector(‘#password’);
const message = document.querySelector(‘#message’);
判断密码强度 ——> 判断有多少种字符组合
数字
字母(大小写)
特殊符号
最小长度 8位起
如果有两种字符组合组成密码 密码强度看作为 弱
如果有三种字符组合组成密码 密码强度看作为 中
如果有四种字符组合组成密码 密码强度看作为 强
const reg = [/\d+/, /[a-z]+/, /[A-Z]+/, /[^A-Z0-9]+/i, /^.{8,}$/];
password.oninput = function () {
const result = reg.map(el => el.test(this.value));
const len = result.pop(); 获得最后一个验证结果
const count = result.reduce((prev, next) => prev + next);
const res = {
1: { mesaage: ‘密码必须包含大小写字母、数字、特殊符号中至少2种类型’, color: ‘red’ },
2: { mesaage: ‘弱’, color: ‘red’ },
3: { mesaage: ‘中’, color: ‘yellow’ },
4: { mesaage: ‘强’, color: ‘green’ },
}
if (len) {
message.textContent = res[count].mesaage;
message.style.color = res[count].color;
switch (count) {
case 1:
message.textContent = ‘密码必须包含大小写字母、数字、特殊符号中至少2种类型’;
message.style.color = ‘red’;
break;
case 2:
message.textContent = ‘弱’;
message.style.color = ‘red’;
break;
case 3:
message.textContent = ‘中’;
message.style.color = ‘yellow’;
break;
case 4:
message.textContent = ‘强’;
message.style.color = ‘green’;
}
} else {
message.textContent = ‘密码长度不足8位’;
message.style.color = ‘red’;
}
}