正则表达式

工作中用到正则的时候真的太多了,比如要撸java,你没有个正则验证某个东西,少说得多写七八行几十行代码,Linux中没有这东西,很多配置文件也得多个好几行,你去搞某些网站,没有正则脚本帮助你,那些命令敲死你都不为过,没办法呀!学呗,去b站找点视频慢慢扒拉着,完了写着写着就会了。

1.概念

regular expression:RegExp(用来处理字符串的规则),可以验证字符串时候符合某个规则(test),把字符串中符合规则的内容捕获到(exec/match)

2.正则表达式基础

创建方式有两种:字面量方式和构造函数方式
区别1:声明方式不同以及对转义符号的处理不同
let reg1=/\d+/;     //字面量方式
let reg2=new RegExp("\\d+","i/m/g");  //构造函数方式有两个参数:(元字符字符串,修饰符字符串)
区别2:对正则中包含某个变量的值的处理不同
let type="fndd";   
reg = /^@"+type+"@$/;
console.log(reg.test("@fndd@")); -->false //字面量方式不能包含某个变量的值

let type="fndd";
reg=new RegExp("^@"+type+"@$");  
console.log(reg.test("@fndd@"));   -->true  //可以匹配

元字符:
    1.量词元字符,设置出现的次数
    *  代表0到多次
    +  代表1到多次
    ?  代表零次或一次
    {n} 出现n次
   {n,}  出现n到多次
   {n,m} 出现n到m次
   2.特殊元字符,单个或者组合在一起代表特殊含义的
   \   转义字符(普通到特殊或者特殊到普通)
   .   除\n(换行符号)以外的任意字符
   ^   以某一元字符作为开始
   $   以某一元字符作为结束
   \d  0~9之间的数字
   \D  非0~9之间的数字(小写和大写的意思相反)
   \w  数字、字母、下划线中的任意一个字符
   \s  一个空白字符(包含空格、制表符、换页符)
   \t  一个制表符(TAB键:四个空格)
   \b  匹配一个单词的边界
   x|y x或者y中的一个字符
   [xyz]  x或者y或者z中的一个字符
   [^xyz] 除过xyz以外的任意字符
   [a-z] 指定a-z范围中的任意字符  [a-z0-9A-Z_]==\w
   [^a-z] 除过a-z范围内的任意字符
   () 分组符号,1.改变运算优先级2.分组捕获3.分组引用
   (?:) 只匹配不捕获
   (?=) 正向预查
   (?!) 负向预查
   3.普通元字符:代表本身含义的东西
    \fndd\  仅代表"fndd"字符串
修饰符:
    i(ignoreCase)  忽略单词大小写匹配
    m(multiline)  多行匹配
    g(global)  全局匹配

 3.元字符详细解析

用浏览器F12里面的console可以写下面的代码进行编码测试,真正了解每个元字符的含义,学完可以去正则表达式的网站去练习!

^ $ 开始结束

let reg =/^\d/;   //数字开头
console.log(reg.test("2018fndd"));  
console.log(reg.test("fndd2018"));

let reg =/\d$/;  //数字结束
console.log(reg.test("2018fndd"));
console.log(reg.test("fndd2018"));

let reg =/\d/;  //包含0-9
console.log(reg.test("2018fndd"));
console.log(reg.test("fndd2018"));

let reg =/^\d$/;  //以数字开头以数字结束
console.log(reg.test("2018fndd"));
console.log(reg.test("fndd2018"));

练习:写一个匹配中国大陆所有手机号码的正则
let reg =/^1\d{10}$/;   //简答版本

\ 转义字符

let reg =/^2.3$/;    //代表匹配2开头中间任意字符3结尾的字符串
console.log(reg.test("23"));
console.log(reg.test("2@3"));
console.log(reg.test("2.3"));

let reg =/^2\.3$/;    //只能匹配2.3这个小数
console.log(reg.test("23"));   
console.log(reg.test("2@3"));
console.log(reg.test("2.3"));


let str =/\d/;      --> false
reg=/^\d$/;
console.log(reg.test(str)); 

let str =/\d/;     --> false
reg=/^\\d$/;
console.log(reg.test(str)); 

let str =/\\d/;     --> false
reg=/^\d$/;
console.log(reg.test(str)); 

let str =/\\d/;   --> false
reg=/^\\d$/;
console.log(reg.test(str));

let str ="\d";    --> false
reg=/^\d$/;
console.log(reg.test(str));   

let str ="\d";   --> false
reg=/^\\d$/;
console.log(reg.test(str)); 

let str ="\\d";    --> false
reg=/^\d$/;
console.log(reg.test(str));   

let str ="\\d";    --> true
reg=/^\\d$/;
console.log(reg.test(str)); 

x|y

let reg=/^18|29/;
console.log(reg.test("18"));  --> true
console.log(reg.test("29"));  --> true
console.log(reg.test("1829")); --> true
console.log(reg.test("182"));  --> true
console.log(reg.test("829")); --> true
因为x|y运算优先级比较混乱,所以加分组()优化如下:
let reg=/^(18|29)$/;     //只能匹配18或者29其中的一个
console.log(reg.test("18"));  --> true
console.log(reg.test("29"));  --> true
console.log(reg.test("1829")); --> false
console.log(reg.test("182"));  --> false
console.log(reg.test("829")); --> false   

[]

[]中括号中的字符大多数代表本身的意思
    let reg=/^[@+]$/;
    console.log(reg.test("@"));    -->true
    console.log(reg.test("+"));    -->true
    console.log(reg.test("@@"));   -->false
    console.log(reg.test("@+"));   -->false
    
    let reg=/^[\d]$/;
    console.log(reg.test("\d"));   -->false
    console.log(reg.test("\\d"));   -->false
    console.log(reg.test("0"));    -->true
    
    let reg=/^[\\d]$/;
    console.log(reg.test("\d"));   -->true
    console.log(reg.test("\\d"));   -->false
    console.log(reg.test("0"));   -->false
    
    let reg=/^[18]$/;    //中括号中的数字代表的是单独的数字,而不是多位数
    console.log(reg.test("1"));    -->true
    console.log(reg.test("8"));    -->true
    console.log(reg.test("18"));  -->false
    
    例子:写一个10~29之间的正则
    let reg=/^[10-29]$/;    //1或者0-2或者9 而不是10-29  错误写法
    let reg=/^[(10-29)]$/;   //同上,错误写法
    let reg=/^[\(10-29\)]$/;  //同上,错误写法  

简单例子:

验证是否为有效数字
let reg=/^[+-]?(\d|([1-9]\d))(\.\d+)?$/;
验证密码为大小写或者6-16位
let reg=/^\w{6-16}$/;
验证真实姓名,汉字取值范围/^[\u4E00-\u9FA5]$/
let reg=/^[\u4E00-\u9FA5]{2,10}('[\u4E00-\u9FA5]{2,10}){0,2}$/;   // '代表长名字中的点
验证邮箱
let reg=/^\w+((-\w+)|(\.w+))*@[a-zA-Z0-9]+((\.|-)[a-zA-Z0-9]+)*\.[a-zA-Z0-9]+$/;
验证身份证号码//前6地区 中间8位出生年月 最后4位abcd d是x或者是数字  c是数字,奇数男偶数女 ab是用其他所有16位算出来的
let reg=/^\d{17}(\d|X)$/;   //错误
let reg=/^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d)(\d|X)$/;   
let reg=/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/;

4.正则的捕获

正则RegExp.prptotype上的方法
exec
test
字符串String.prototype上的方法
replace
match
splite

exec捕获
1.捕获的正则必须和字符串匹配,正确则输出数组,否则就输出null
2.每次执行一次exec只能捕获一次符合正则的内容,被称为正则捕获的懒惰性
let str="fangnidouding2018jianbo1987";
let reg=/\d/;
console.log(reg.exec(str));  -->["2", index: 13, input: "fangnidouding2018jianbo1987"]
console.log(reg.lastIndex(str)); -->0  
//懒惰原因:字符串下标索引值没有被改变,每次都是从0位开始查找,一直到匹配上然后又回到0

let str="fangnidouding2018jianbo1987";
let reg=/\d+/g;   //解决正则捕获的懒惰性给后面加全局修饰符g
console.log(reg.exec(str));   -->["2018", index: 13, input: "fangnidouding2018jianbo1987"]
console.log(reg.lastIndex);   -->17
console.log(reg.exec(str));   -->["1987", index: 23, input: "fangnidouding2018jianbo1987"]
console.log(reg.lastIndex);   -->27
console.log(reg.exec(str));   -->0
console.log(reg.lastIndex);   -->null
console.log(reg.exec(str));   -->["2018", index: 13, input: "fangnidouding2018jianbo1987"]
console.log(reg.lastIndex);   -->17
1.每次匹配完毕会改变下标的检索位置
2.字符串检索完之后会输出null,下标会循环到0,然后循环进行下一次检索
---------------------------------------------------------------------------------------------
test的匹配和捕获
let str="fangnidouding2018jianbo1987";  
let reg=/\d+/g;   
console.log(reg.test(str));   -->true
console.log(reg.lastIndex);   -->17   //可以看出test匹配完之后会修改下标值

let str="{0}年{1}月{2}日";  
let reg=/{(\d+)}/g;   
console.log(reg.test(str));  -->true
console.log(RegExp.$1);    -->0
console.log(reg.test(str));   -->true
console.log(RegExp.$1);    -->1
console.log(reg.test(str));   -->true
console.log(RegExp.$1);    -->2
console.log(reg.test(str));   -->true
    console.log(RegExp.$1);    -->2   //RegExp.$1~RegExp.$9取值范围,获取当前正则匹配后第一个到第九个分组的信息
 
--------------------------------------------------------------------------------------------
match捕获
let str="fangnidouding2018jianbo1987";
let reg=/\d+/g;   
console.log(str.match(reg));  -->["2018", "1987"]  //可以输出所有匹配规则的字符串
--------------------------------------------------------------------------------------------
let reg=/^(\d{6})(\d{4})(\d{2})(\d{2})\d{2}(\d)(?:\d|X)$/;  //?:的意思是只匹配不捕获,只拿有用的信息
let str="610527199311071107";
console.log(reg.exec(str));
console.log(str.match(reg)); -->["610527199311071107", "610527", "1993", "11", "07", "0", index: 0, input: "610527199311071107"]
--------------------------------------------------------------------------------------------
let str="book";
let reg=/^[a-zA-Z]([a-zA-Z])\1[a-zA-Z]$/;    //()后面出现\1或者\任意数字的意思是此分组多引用一次
console.log(reg.test("good"));   --ture
console.log(reg.test("keep"));   --ture
console.log(reg.test("tomm"));   --false

--------------------------------------------------------------------------------------------
正则捕获的贪婪性:
let str="fangnidouding2018jianbo1987";
let reg=/\d+/g;   
console.log(str.match(reg));  -->["2018", "1987"]  //每次捕获的时候,都是按照最长结果来匹配的

let str="fangnidouding2018jianbo1987";
let reg=/\d+?/g;     //量词元字符后面加?含义是取消捕获的贪婪性
console.log(str.match(reg));  --> ["2", "0", "1", "8", "1", "9", "8", "7"]
-------------------------------------------------------------------------------------------
小结?的5大作用:
?左边是非量词元字符,代表出现0~1次
?左边是量词元字符,代表取消捕获的贪婪性
(?:)只匹配不捕获
(?=)正向预查
(?!)反向预查
-------------------------------------------------------------------------------------------
replace捕获
let str="fndd2018fndd1987";
str =str.replace(/fndd/g,"芳妮");  
console.log(str); -->芳妮2018芳妮1987

将2018-01-02替换成2018年1月2日
let str="2018-01-02";
let reg=/^(\d{4})-(\d{1,2})-(\d{1,2})$/;
str=str.replace(reg,"$1年$2月$3日");
console.log(str);
//还可以用[str].replace([reg],[function])来处理
let str="2018-01-02";
let reg=/^(\d{4})-(\d{1,2})-(\d{1,2})$/;
str=str.replace(reg,(big,$1,$2,$3)=>{
    console.log(big,$1,$2,$3);    -->2018-01-02 2018 01 02
});
console.log(str);
//优化如下
let str="2018-01-02";
let reg=/^(\d{4})-(\d{1,2})-(\d{1,2})$/;
str=str.replace(reg,(...arg)=>{
    let [,$1,$2,$3]=arg
    $2.length<2?$2="0"+$2:null;
    $3.length<2?$3="0"+$3:null;
    return $1+"年"+$2+"月"+$3+"日";    
});
console.log(str);

记得多练习,多练习在多练习,最后附上在线测试网址

https://tool.oschina.net/regex/

https://c.runoob.com/front-end/854

http://tool.chinaz.com/regex/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值