正则表达式 – 渡一袁老师
- 默认分类
- 2023-09-25
- 1690热度
- 0评论
基础
-
- 特殊字符
. // 匹配任意一个字符 ^ // 匹配字符串开始 $ // 匹配字符串结束 例如: 规则:a123...$ a1234 false a123456 true b12345677 false
- 转义符:\
\n // 换行符 \r // 回车符 \t // 制表符(Tab键) \s // 任意空白字符 \S // 除了任意空白字符以外字符(\s取反) \b // 单词边界 \B // 非单词边界 \d // 匹配一个0-9的数字 \D // 非 数字 \w // 数字、字母、下划线 \W // 非 数字、字母、下划线 \un // 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符
- 字符集:[]
[字符范围] // 匹配中括号里任意一个字符 [^字符范围] // 注意:^符号如果加在字符串规则最前面表示以X开始,如果放字符集里最前面表示对字符范围取反,例如:[^0-9]匹配非数字相当于\D 匹配中文:[\u4e00-\u9FA5]
- 量词:前面的规则出现的次数
- 或者:多个规则之间,适用或者
|
,表示多个规则任选其一
JS中的应用
js中,正则表达式表现为一个对象,该对象是通过构造函数RegExp
创建正则对象
-
字面量模式
-
构造函数模式
// reg1等价于reg2
var reg1 = /^-?\d+(\.0+)?$/;
var reg2 = new RegExp("^-?\d+(\.0+)?$");
// 替换敏感词
var senWords = ["抽烟","喝酒","烫头"];
function removeSensitiveWords (s,rep) {
// 此处用需要用构造函数模式 /抽烟|喝酒|烫头/g
var reg = new RegExp(senWords.join("|"),"g");
return s.replace(reg,rep);
}
console.log(removeSensitiveWords("skjf抽地烟daf喝酒95995烫头发66","***")); // skjf抽地烟daf***95995***发66
正则实例成员
- global:全局匹配
- ignoreCase:忽略大小写
- multiline:多行匹配
- exec方法:execute,执行匹配,得到匹配结果
- test方法:验证某个字符串是否满足规则
// 匹配一个字符串中 中文出现的次数 var str = "fsf的接口拉菲接sdsd多少sd问问sdddsd发"; var reg = /[\u4e00-\u9fa5]/g; var n = 0; while (reg.test(s)) { n++; } console.log(n); // 11
贪婪模式正则表达式,默认情况下,适用贪婪模式(尽可能多匹配)
在量词后,加上
?
字符串中正则方法
- split:以某种规则分割字符串
// 把一个字符串按照非数字、字母、下划线规则分割 var str = "abc def\tgg,ffh&&j"; str.split(/\W/) // ['abc', 'def', 'gg', 'ffh', '', 'j']
- search:得到匹配下标
var str = 'abgdkljkf' str.search(/d/g) // 3
- match:得到匹配结果
var str = "1234abc123aaa"; var result = str.match(/\d+/g); console.log(result); // ['1234', '123']
- replace:替换
// 替换字符串中首字母为大写 var str = 'hello world'; str = str.replace(/\b[a-z]/g, function(match) { return match.toUpperCase(); }) console.log(str) // Hello World // 替换首字母为大写,并且去掉空格换行制表符都特殊字符 var str = 'hello world\tjavascript\nyes'; str = str.replace(/\s*\b[a-z]\s*/g,function(match){ return match.toUpperCase().trim(); }) console.log(str) // HelloWorldJavascriptYes
进阶
捕获组
()
包裹的部分叫做捕获组,捕获组会出现在匹配结果中
语法:()
// 得到每一个日期,并且得到每个日期的年月日
var s = "2015-5-1, 2016-6-18, 2000-08-28";
var reg = /(\d{4})-(\d{1,2})-(\d{1,2})/g;
while (result = reg.exec(s)) {
var r = `${result[0]}, ${result[1]}, ${result[2]}, ${result[3]}`;
console.log(r);
// 2015-5-1, 2015, 5, 1
// 2016-6-18, 2016, 6, 18
// 2000-08-28, 2000, 08, 28
}
捕获组占位符:两种形式
var s = "2015-5-1, 2016-6-18, 2000-08-28";
var reg = /(\d{4})-(\d{1,2})-(\d{1,2})/g;
// 1.
// 占位符:$1表示第一个捕获组,$2表示第二个捕获组
// s = s.replace(reg,"$1/$2/$3"); // 2015/5/1...
/**
* 2.
* reg: 正则表达式规则
* match: 匹配的结果
* g1/g2/g3:捕获组
*/
s.replace(reg,function(match,g1,g2,g3){
console.log(match,g1,g2,g3);
// 2015-5-1, 2015, 5, 1
// 2016-6-18, 2016, 6, 18
// 2000-08-28, 2000, 08, 28
})
()
最前方加上?<name>
var s = "2015-5-1, 2016-6-18, 2000-08-28";
var reg = /(?<year>\d{4})-(?<month>\d{1,2})-(?<day>\d{1,2})/g;
while (result = reg.exec(s)) {
console.log(result.groups,result.groups.year,result.groups.month,result.groups.day);
// {year: '2015', month: '5', day: '1'} '2015' '5' '1'
// {year: '2016', month: '6', day: '18'} '2016' '6' '18'
// {year: '2000', month: '08', day: '28'} '2000' '08' '28'
}
()
最前方加上?:
反向引用
反向引用:引用之前的捕获组
语法:\n
// 【\1】: 捕获组后面加上“\1”,引用前面的捕获组重复一次
var reg = /(\d{2})\1/g;
var s = "1313";
console.log(reg.test(s)); // true
var s2 = "1334";
console.log(reg.test(s)); // false 捕获到的是13 重复后是1313
// 例1:找出该字符串中连续的字符(abcg)
// var s = "aaaaaabbbbbbcccccccdefgggggg"
var s = "aaaaaabbbbbbcccccccdefgggggg";
var reg = /(\w)\1+/g;
while (result = reg.exec(s)){
console.log(result[1]); // a b c g
}
正向断言(预查)
语法:?=
// 找出后面是数字的字母(不要后面数字,但是要检查后面有没有数字) :f a d
var s = "sdsdsf345dsa45dafd5533434trt";
var reg = /[a-z-A-Z](?=\d+)/g; // 此处()里面不是捕获组 而是检测前面的字母后面是否有数字(\d+)
while (result = reg.exec(s)) {
console.log(result); // f a d
}
// 面试题:把一个数字从右到左,每隔三位加上一个,
var s = '893889659';
// 3个数字出现一次或多次(整个是一个正向预查)
var reg = /\B(?=(\d{3})+$)/g; // 如果不加\B 则刚好是3的倍数时 第一位会出现,
s = s.replace(reg, ",");
console.log(s); // 893,889,659
负向断言(预查)
正向断言:检查某个字符后面的字符是否不满足某个规则,该规则不成为匹配结果,并且不成为捕获组
语法:
// 找出后面没有数字的字母:a f r s
var s = "afg5d6rsp9";
var reg = /[a-zA-Z](?!\d+)/g;
while (result = reg.exec(s)) {
console.log(result); // a f r s
}
// 面试题:判断密码强度(要求密码中必须出现小写字母、大写字母、数字、特殊字符(!@#_,.))
// ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#_,.]): 这一部分是检查是否存在大/小写字母,数字,特殊字符
// 如果满足要求再去匹配6-12位
var reg = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#_,.]).{6,12}$/;
console.log(reg.test("24dff34A.")); // true
console.log(reg.test("24dff34A")); // false
console.log(reg.test("24dff34A.888888888")); // false
/**
* 判断密码强度综合版
* 密码长度必须是6-12位
* 出现小写字母、大写字母、数字、特殊字符(!@#_,.) -> 强
* 出现小写字母、大写字母、数字 -> 中
* 出现小写字母、大写字母 -> 弱
* 其他 -> 不满足要求
*/
function judgePwd(pwd) {
if(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#_,.]).{6,12}$/.test(pwd)){
return "强";
} else if (/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{6,12}$/.test(pwd)){
return "中";
} else if (/^(?=.*[a-z])(?=.*[A-Z]).{6,12}$/.test(pwd)){
return "弱";
} else {
return "不满足要求";
}
}
console.log(judgePwd("ABGcdf58.")); // 强
console.log(judgePwd("ABGcdf88")); // 中
console.log(judgePwd("ABGcdf")); // 弱
console.log(judgePwd("ABGcd")); // 不满足要求