正则-生成验证规则神器
正则的创建
- 字面量创建方式
let reg = /^$/
- 实例创建 RegExp
- 构造函数创建方式,可以实现正则的拼接
- 传递的参数是一个字符串
- 利用字符串可以拼接的特点,能够实现正则传递变量
- 可以引入变量
- 如果出现转义字符,转义前面再加一个\
let reg = new RegExp('')// */// let m = 'moon';// let reg1 = /^$/// let reg = new RegExp('^'+m+'/d$')// console.log(reg)let str = '\\d';let str1 = '\D'console.log(str) // '\d'console.log(str1) // 'D'
------------------------------------------------------------var name="js"var reg = new RegExp(name)///js/var reg1 = new RegExp("\\d"+name)///\djs///如果出现转义字符,转义前面再加一个\console.log(reg)
正则的基础
正则:属于引用数据类型
用来处理字符串的一个规则
正则由元字符和修饰符组成
test:检测,匹配:如果检测成功,返回true,没有检测成功返回false
exec:捕获;返回一个数组;其中第一项就是捕获到的内容,第二项捕获内容开始的索引,第三项是要检测的整个字符串的整体
match:
- 字符串的方法:匹配
- 他是字符串的一个方法,在String类的原型上,这个方法传递一个正则,
- 返回是是一个数组
- 如果正则不加g,跟exec返回值一样
- 加g;全局捕获;捕获多次,把符合正则内容的字符串都放到一个数组中;
- 缺点:如果要进行分组捕获,那他就拿不到分组捕获的内容了
注意:如果正则捕获不到内容返回值就是null
var str="ls199hh88";
var reg = /\d+/g;
//console.log(reg.test(str))
//console.dir(reg)
console.log(reg.exec(str))//["199", index: 7, input: "ls199hh88", groups: undefined]
console.log(reg.exec(str))//["88", index: 12, input: "ls199hh88", groups: undefined]
-------------------------------------------------------------------------------------let reg = /^3$/console.log(reg.test('3werr')) // falseconsole.log(reg.test('32'))console.dir(RegExp)console.log(reg.exec('3'))// ["3", index: 0, input: "3", groups: undefined] // // 数组的第一项是捕获的内容// index是捕获内容的开始位置的做引// input是原字符串
正则的规则
正则由两部分组成:元字符和修饰符
修饰符:就是把正则额外的修饰一下
i: 不区分大小写
m:多行匹配
g:全局匹配元字符:量词元字符、普通元字符、特殊元字符 (在正则中有特殊的含义的一些字符)
量词元字符:代表出现的次数
*:代表0到多次
+:出现一到多次
?:出现0到1次
{n}:出现n次
{n,}:至少出现n次
{n,m}出现n到m次特殊元字符:单个或者多字符组合在一起具有特殊意义
\:转义字符:可以把普通元字符字符转换为特殊的元字符,也可以把特殊元字符转换为普通元字符 //
. :除了换行符以外的任意字符
^:以什么什么开头 //
$:以什么什么结尾 //
\n:换行符
\d:0-9之间的数字 //
\D:0-9以外的任意字符
\w:数字、字母、下划线 ,匹配包含下划线的任意字符[0-9a-zA-Z_]
\W:[^0-9a-zA-Z_]
\s:空白字符
\t是制表符,空格,为4个字符的空格
\b:单词边界
\B:匹配非单词边界
x|y:取x或y的任意一个 //
[xyz]:取x、y、z中的任意一个 //
[a-z]:在a到z范围内取一个 //
[^a-z]:取反,除了xyz中的任何一个
():分组 //
(?: ) :只匹配不捕获(没有空格)
(?=):正向预查
(?!):负向预查普通元字符:
let reg = /name/
[\s\S] 意思是匹配所有 空白复字符+非空白字符 , 说白了也就是全部字符都可以
js去除字符串中的所有空格:
str.replace(/\s/g,"");
\s匹配单个空格字符,包括ASCII空格,制表符,换行符,回车符,垂直制表符和换页符
正则的分组 ()
1、改变了正则的优先级
// let reg = /^(18|29)$/ //18开头或者29结尾// console.log(reg.test('18')) // true// console.log(reg.test('29')) // true// console.log(reg.test('189')) // true// console.log(reg.test('129')) // true// console.log(reg.test('28')) // false
2、分组引用
- 分组引用
- ([a-z])\1:相当于把前面一样的值拿过来,在出现一次
- \1:代指和第一个分组一模一样的内容
let str = 'moon'
let reg = /^[a-z]{4}$/
console.log(reg.test('asdf')) // true
let reg = /^[a-z]([a-z])\1\1[a-z]$/
console.log(reg.test('foood')) // true
3、分组捕获
- 正则捕获的时候会把最大的内容捕获一次,然后在把每一个分组捕获一次
- 用于小正则的捕获
- 小括号要进行捕获,从左往右依次进行捕获
let reg = /^([a-z])([a-z])\1\2$/
console.log(reg.test('qwqw')) // true
4.转义
- 转义字符( \可以把在正则中有特殊意义的字符转义为普通字符,也可以把普通字符转换以有意义的字符)
let reg = /^23\.45$/.在正则中代除换行符外的任意字符\可以把有特殊意义的元字符转换为普通字符,也可以把普通字符转换为有意义的元字符console.log(reg.test('23e45')) // falseconsole.log(reg.test('23.45')) // true// let reg = /^2.3$/ // 中间的点可以匹配换行符外的所有字符// console.log(reg.test('2.3')) // true// console.log(reg.test('2@3')) // true// console.log(reg.test('2f3')) // true// let reg = /^2\.3$/ // 我只想匹配数组2.3// console.log(reg.test('2.3')) // true// console.log(reg.test('2@3')) // fasle// console.log(reg.test('2f3')) // false
- []
- 一般情况在中括号里出现的字符都是普通字符
- 中括号中不识别多位数
1、中括号里放的一般都是普通字符let reg = /^[@+]$/console.log(reg.test('+')) // trueconsole.log(reg.test('@')) // truelet reg = /^[\\d]$/console.log(reg.test('d')) // trueconsole.log(reg.test('\\')) // true
2、中括号不允许出现多位数let reg = /^[12-57]$/ // 1 2-5 7console.log(reg.test('30')) // falseconsole.log(reg.test('1')) // trueconsole.log(reg.test('4')) // trueconsole.log(reg.test('7')) // trueconsole.log(reg.test('6')) // false
正则的正负向预查
- 正向预查 ?=
//ls后面必须跟haorenvar reg=/ls(?=haoren)/;console.log(reg.test("lshaoren"))//true 这个正则能够匹配ls后面跟着haoren字符串
- 负向预查 ?!
- 如果ls后面跟着不是haoren的,能够匹配成功,返回true,否则返回false;
//ls后面必须跟不是haoren的var reg=/ls(?!haoren)/;console.log(reg.test("lshaoren"))//false
正则的捕获
- 小括号:也要进行以此捕获,从左往右依次进行捕获
- ?: 取消捕获(放在哪取消哪)
正则的懒惰性
- 在正则捕获时,如果第一次捕获到内容,就不会再继续捕获(这叫正则的懒惰性)
- 懒惰性:正则找到符合正则的值以后,就不再捕获了
- 取消正则的懒惰性,用正则的修饰符g
- g:每捕获一次,当前正则的lastIndex就会被修改成下一轮开始捕获的索引位置
- reg.lastIndex:是下一轮捕获开始的索引位置
数组的第一项是最大的捕获
以后数组的每一项是分组捕获的内容
index:第一次捕获的内容的开始位置的索引
input:原字符串
function myExec(str){if(!this.global){return this.exec(str)};let ary = [];let res = this.exec(str)while(res){ary.push(res[0])res = this.exec(str)}return ary.length === 0?null:ary;
};
RegExp.prototype.myExec = myExec;
console.log(reg.myExec(str))
正则的贪婪性
- 正则在匹配的时候能多匹配一个就多匹配一个,这就是正则的贪婪性
- 在量词元字符的右边出现?,那就是取消正则的贪婪性
- 贪婪性
- ?放在量词的后面是取消捕获的贪婪性的
// 正则的贪婪性let str = 'ls2019ls2020';let reg = /\d+?/gconsole.log(str.match(reg)) //["2", "0", "1", "9", "2", "0", "2", "0"]// 正则在匹配的时候能多匹配一个就多匹配一个,这就是正则的贪婪性// 在量词元字符的右边出现?,那就是取消正则的贪婪性
exec的捕获
- exec:他是正则实例的一个公有属性,他是用来捕获符合规则的字符串的
- 1、返回值:是一个数组,如果捕获不到就是null
- 2、如果是数组
- 1、第一项是最大的捕获内容
- 2、以后数组的后几项就是分组捕获的内容
- 3、index是第一次捕获位置的索引
- 4、input是原字符串
- 3、如果你只匹配不捕获,就在小括号里加?:
- 4、exec只能捕获到第一次出现的符合正则规则的内容(这是正则捕获的懒惰型,默认只捕获第一个)
let reg1 = /^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d)(\d|X)$/;let str = '13073020020528421X';console.log(reg1.exec(str))//["13073020020528421X", "130730", "2002", "05", "28", "1", "X", index: 0, input: "13073020020528421X", groups: undefined]let reg = /\d{2}/g;let str = 'w33w33ww';console.dir(reg)// 如果正则不加g,那每一次去捕获,捕获到的都是第一次符合规则的内容lastIndex的值不会变,都是0// 如果正则加上g,那每捕获一次,正则的lastIndex就会记录当前捕获到的内容的最后一项索引,下次再捕获的时候从记录的索引的基础上+1,继续捕获// console.log(reg.exec(str))// console.log(reg.lastIndex)// console.log(reg.exec(str))// console.log(reg.lastIndex)// console.log(reg.exec(str))//match用exec捕获来模拟// function myExec(str){// // 如果正则不加g,那正则的私有属性global的值就是false,// // 就给他捕获一次直接return就好了// if(!this.global){// return this.exec(str)// };// let ary = []; // 用来存放每一次捕获到的内容// let res = this.exec(str) // 重新进行捕获// while(res){// // 每捕获一次就往ary里push一次捕获到的内容// ary.push(res[0])// // 然后在继续捕获// res = this.exec(str)// }// // 如果正则第一次就捕获不到,while就不会执行,那ary是空数组,直接给他return null就好了// return ary.length === 0?null:ary;// };// RegExp.prototype.myExec = myExec;// console.log(reg.myExec(str)) // ['33', '33']console.log(str.match(reg)) // ['33', '33']
通过match捕获
- match:
- 字符串的方法:匹配
- 他是字符串的一个方法,在String类的原型上,这个方法传递一个正则,
- 返回是是一个数组
- 如果正则不加g,跟exec返回值一样
- 加g;全局捕获;捕获多次,把符合正则内容的字符串都放到一个数组中;
- 缺点:如果要进行分组捕获,那他就拿不到分组捕获的内容了
- 自己封装的捕获方法
// 封装一个方法,当正则进行捕获的时候要拿到每一次全局捕获的内容,还要拿每一次分组捕获的内容function execAll(str){// 如果正则不加g,那正则实例身上的私有属性global就是false,反之就是trueif(!this.global){// 直接给他捕获一次return 出去return this.exec(str)}let big = [], // 创建一个大数组用来存储全局捕获的内容small = [], // 创建一个小数组用来存储分组捕获的内容res = this.exec(str) // 创建一个变量,用来存储每一次捕获的内容while(res){big.push(res[0])small.push(res[1])// 重复执行正则捕获这个动作res = this.exec(str)}return big.length === 0?null: {big,small}// 把捕获到的内容return出去// console.log(res)}RegExp.prototype.execAll = execAll;console.log(reg.execAll(str))
replace捕获
- replace :字符串的替换;原有字符串不发生改变,会得到一个替换之后的返回值;
- 每次只能替换一个
- 结合正则
- 用正则对字符串进行捕获,把捕获到的内容替换成后面的字符串
- 正则和回调函数
- 正则对字符串进行捕获,并且将回调函数的返回值覆盖捕获到的内容;
- 正则捕获几次,这个回调函数就执行几次
- 回调函数执行时,会把每一次捕获的内容当做实参传递给回调函数里
- 回调函数的返回值会把每一次捕获的内容替换
let str = 'ls33ls33'// 我想把 'ls'替换为 'lshaoren'// str = str.replace('ls', 'lshaoren').replace('ls', 'lshaoren')// str = str.replace(/ls/g , 'lshaoren')str = str.replace(/ls/g,function(){console.log(arguments)/* 1、正则匹配几次,这个回调函数就执行几次2、回调函数的返回值会把每一次捕获的内容替换3、回调函数执行时,会把每一次捕获的内容当做实参传递给回调函数里*/return 'lshaoren'})console.log(str)
---------------------------------------------------var str = "123or456";var newStr = str.replace(/\d+/g,function(a,b,c){console.log(a);// 第一个参数是捕获到的内容console.log(b);// 第二个参数捕获的内容开始的索引位置console.log(c);// 原来的字符串// console.log(100);// return 1;});console.log(newStr);
例子:正则表达式
- 匹配有效数字:1、1.5、+2、0、-1
- 开头有可能是±号,也有可能没有 ?
- 如果是个位数[0-9] 两位数 ([1-9]\d+)
- 小数 (.\d+)? 可以不出现,也可以出现1次
// let reg = /^[+-]?(\d|([1-9]\d+))(\.\d+)?$/// console.log(reg.test('2')) // true// console.log(reg.test('2.5')) // true// console.log(reg.test('-2')) // true// console.log(reg.test('+2')) // true// console.log(reg.test('2.')) // false// console.log(reg.test('2..')) // false// console.log(reg.test('3.1415926')) // true
- 匹配密码
- 6到16位组成
- 由数字、字母、下划线组成
// function fn(str){// if(str.length<6 || str.length>16 ){// alert('密码不符合规范');// return// }// let ary = ['2','_','....'] // 由数字、字母、下划线组成// for (var i = 0; i < str.length; i++) {// if(!ary.includes(str[i])){// alert('密码不符合规范');// return// }// }// }
- 邮箱
let reg = /^[a-zA-Z0-9-_]+@[a-z0-9]+(\.[a-z]+)+$///12344@qq.com// let reg = /^[a-zA-Z0-9-_]+@[a-z0-9]+(\.[a-z]+)+$/;// console.log(reg.test('12344@qq.com.cn')) // true// console.log(reg.test('12344@qq.com')) // true// console.log(reg.test('12344@qq..com')) // false// console.log(reg.test('@qq.com')) // false// console.log(reg.test('-@qq.com')) // false
- 匹配中文名字 [\u4E00-\u9FA5]
//let reg = /^[\u4E00-\u9FA5]{3,6}(·[\u4E00-\u9FA5]{2,6}){0,2}$/// let reg = /^[\u4E00-\u9FA5]{2,6}(·[\u4E00-\u9FA5]{2,6}){0,2}$/;// console.log(reg.test('爱新觉罗·溥仪'))// console.log(reg.test('阿诺德·施瓦辛格'))
- 身份证
- 18位
- 前6位是省市
- 中间8位是生日
- 倒数四位
- 前两位是公安局代码
- 第三位是性别,奇数是男,偶数是女
- 最后一位是数字,有可能是X
//先确定最后一位
// let reg = /^\d{17}(\d|X)$/
//前六+中八
// let reg1 = /^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d)(?:\d|X)$/;
// ?: 只匹配不捕获
//中八
// let reg2 = /^(\d{6})([1-2]\d{3})((0[1-9])|(1[0-2]))((0[1-9])|([1-2][0-9])|(3[0-1]))\d{2}(\d)(\d|X)$/;// let reg3 = /^(\d{6})([1-2]\d{3})((0[1-9])|(1[0-2]))((0[1-9])|([1-2]\d)|(3[0-1]))\d{2}(\d)(\d|X)$/;
// // 年 1xxx - 2xxx
// // 月 01-09 10-12
// // 日 01-09 10-29 30-31// let res = reg1.exec('13073020020528421X');
// console.log(res[2] + '年' + res[3] +'月' +res[4] +'日')
// // console.log(reg2.test('13073030020528421X'))
// console.log(reg1.exec('13073020020528421X'));
// console.log(reg1.exec('13073020020528421X222')); // null
// 正则捕获不到是null
// ["13073020020528421X", "130730", "2002", "05", "28", "1", "X", index: 0, input: "13073020020528421X", groups: undefined]1、数组的第一次最大的捕获2、以后数组的每一项是分组捕获的内容3、index:第一次捕获的内容的开始位置的索引4、input:原字符串let str = '33ss33ss';let reg = /\d{2}/gconsole.log(reg.test(str))console.log(reg.exec(str))console.log(reg.lastIndex)
使用replace的例子
- 用函数把good good study day day up首字母变成大写
function toFirstUpperCase() {let reg = /\b([a-z])[a-z]*\b/g;// console.log(str.match(reg))let newStr = this.replace(reg, function () {// console.log(big, small)// console.log(arguments)let [word, firstWord] = arguments // 把每一次捕获的单词和分组捕获的单词首个字母解构出来firstWord = firstWord.toUpperCase() // 把首字母转大写word = word.slice(1) // 把单词从第二项开始截取return `${firstWord}${word}` // 最后把转大写的开头字母和截取的字母组合到一起对捕获的内容进行替换})return newStr}String.prototype.toFirstUpperCase = toFirstUpperCase;let str = 'good good study day day up';console.log(str.toFirstUpperCase())
- 字符串时间格式化
- 在后台工作中会给我们返回字符串格式的时间
function formatTime(template = '{0}年{1}月{2}日 {3}时{4}分{5}秒'){let timeAry = this.match(/\d+/g);// 把字符串里的年月日时分秒都拿到以数组的格式 ["2019", "12", "3", "12", "10", "3"]// let template = '{0}年{1}月{2}日 {3}时{4}分{5}秒';// 编写一个模板,一会用来进行替换template = template.replace(/\{(\d)\}/g, function(content, index){// index是每一次分组捕获的内容// console.log(content, index)// console.log(timeAry[index])let time = timeAry[index] || "00"; // 如果index获取不到对应的值,那就默认赋值为 "00"time.length<2? time = "0"+time:null;// 如果获取的时间不足十位就补零return time})return templateconsole.log(timeAry)}String.prototype.formatTime = formatTime;console.log(time.formatTime('{1}~{2} {3}:{4}'))
- 获取网址=号左右
let url = 'http://www.baidu.com?name=erYa&age=18#index';function queryUrlParams() {let reg = /([^?=&#]+)=([^?=&#]+)/g;let obj = {}; // 创建一个空对象,用来存储一会处理的键值对this.replace(reg, (content, key, value) => {// content是每一次全局捕获的内容,// key是每一次第一个分组捕获的内容(作为属性名)// value是每一次第二个分组捕获的内容(作为属性值)obj[key] = value;});// 把url里的参数捕获出来,以键值对的形式赋值给obj对象this.replace(/#([^?=&#]+)/, (content, value) => {// value是每一次分组捕获的内容(作为属性值)obj['hash'] = value;})// 把url里的hash值捕获出来,以键值对的格式赋值给obj对象return obj;// 最后把obj对象return 出去}String.prototype.queryUrlParams = queryUrlParams;console.log(url.queryUrlParams());
- 首字母小写转大写
var str = "my name is niu ,i am 28 years old";var newStr = str.replace(/[a-z]+\b/g, function (a) {return a[0].toUpperCase() + a.slice(1)})console.log(newStr);
- 把数字转成中文
var str = "20191214";var ary = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", "万", "仟"];var newStr = str.replace(/\d/g, function (a) {return ary[a]})console.log(newStr);
- 把下面时间格式化成2019年12月24日16时02分30秒
var str = "2019-12-24 16:02:30";var ary = ["年", "月", "日", "时", "分", "秒"];var newStr = "";var i = 0;str.replace(/\d+/g, function (a, b) {newStr += a + ary[i++];})console.log(newStr);
- 加千分符,给下面的数字加’,'使其成为13,234,567,753,224
var str = "13234567753224";//1var newStr = str.replace(/^(\d{1,3})((\d{3})+)$/, function (a, b, c, ) {console.log(arguments);//["13234567753224", "13", "234567753224", "224", 0, "13234567753224", callee: ƒ, Symbol(Symbol.iterator): ƒ]var part2 = c.replace(/\d{3}/g, function (d,e) {return ","+d})return b+part2})console.log(newStr);//2var str ="1234657753224";var i=0;var newStr=str.replace(/\d/g,function(a,b){debugger;if((str.length-b-1)%3===0&&str.length-1!=b){return a+","}else{return a}})console.log(newStr);//3str.toLocaleString('en-US');
结束语
- 感觉还可以的可以点赞、收藏加关注呦~
- 推荐三款正则可视化工具
正则-生成验证规则神器相关推荐
- 验证规则构建神器 FluentValidation.md
上一篇文章<MediatR在.NET应用中的实践>中,我们在讲MediatR的管线内容时,提到过可以在管线中增加 Command/Query 的验证.今天我来带领大家了解一个.NET技术领 ...
- vue 表单验证正则_vue elementUI如何自定义表单验证规则
一.elementUI自带了一部分表单验证规则,本文讲解如何使用自定义验证规则来完成密码的二次验证. 1.1.首先添加验证邮箱和电话规则和正则表达式// 验证邮箱的规则 var checkEmail ...
- SpringBoot-Security-用户权限分配-配置验证规则
Spring Security配置 Spring Security配置是通过 @EnableWebSecurity注释和WebSecurityConfigurerAdapter共同提供基于网络的安全性 ...
- yii2中的rules验证规则
2019独角兽企业重金招聘Python工程师标准>>> Rules验证规则:required : 必须值验证属性||CRequiredValidator 的别名, 确保了特性不为空. ...
- php validate form,laravel 中validate验证规则 利用FormRequest进行数据验证
namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class AddCartRequest extend ...
- php字段验证规则,详解ThinkPHP中自动验证及验证规则
本篇文章详细介绍了thinkphp中自动验证及验证规则的方法,希望对学习thinkphp的朋友有帮助! 详解ThinkPHP中自动验证及验证规则 ThinkPHP 内置了数据对象的自动验证功能来完成模 ...
- php自动验证,ThinkPHP 自动验证及验证规则详解
ThinkPHP 自动验证 ThinkPHP 内置了数据对象的自动验证功能来完成模型的业务规则验证.自动验证是基于数据对象的,而大多情况下数据对象是基于 $_POST表单 (不是绝对的)创建的. 基本 ...
- SpringBoot整合Drools规则引擎动态生成业务规则
最近的项目中,使用的是flowable工作流来处理业务流程,但是在业务规则的配置中,是在代码中直接固定写死的,领导说这样不好,需要规则可以动态变化,可以通过页面去动态配置改变,所以就花了几天时间去研究 ...
- table中加表单元素怎么验证_el-table嵌入表单元素注意事项(验证规则prop写法与数据初始化)...
场景:在el-table表格中嵌入表单元素 绑定数据: table : :data="planFormData.allocationPlan" el-form-item: v-mo ...
最新文章
- 有没有想过,自己手写一个连接池?
- scrapy windows
- [hiho1159] Poker
- 【ABAP】OO ALV 概述
- 【图像超分辨率】Multi-scale Residual Network for Image Super-Resolution
- java awt区域_java的awt包中有没有表示区域的类或者方法,可以传递一个Rectangle
- Java面试题:JDK不同版本处理IO流异常的标准代码
- 线程超时 php-fpm,php-fpm线程僵死导致网站无响应
- Winform界面中实现通用工具栏按钮的事件处理
- 算法笔记_101:蓝桥杯练习 算法提高 身份证号码升级(Java)
- 生成检测报告在哪_惠检LIMS系统在材料检测行业的应用
- 论文:Scalable and accurate deep learning for electronic health records研读笔记
- 网络基础知识之报文格式介绍
- 施努卡:密封环ccd检测(密封圈视觉检测的原理 )
- bbys_tu_2016(ret2text)
- 计算机 access数据库,计算机等级考试二级ACCESS数据库基本使用方法
- ICCV 2021 | 当Transformer遇见自监督学习!Facebook重磅开源DINO
- 如何解决海外邮件发不出去
- zbb20180913 java thread volatile与synchronized区别
- mysql动力节点百度云_动力节点MySQL数据库视频 百度云 网盘 下载