正则表达式巧入门

前言:

本文介绍正则表达式入门的一些知识,用来做笔记用的,很系统~
正则表达式是匹配模式,要么匹配字符,要么匹配位置。这是正则表达式核心。
匹配字符是一个个扫描,类似于用for循环一样。 当然,你可以任意定义它的匹配方式。
注:正则是使用JavaScript写的,阅读本文需要一定的时间和耐心。

两种模糊匹配

如果正则只有精确匹配是没多大意义的,比如 /hello/,也只能匹配字符串中的 “hello” 这个子串。

var regex = /hello/; console.log( regex.test("hello") ); // => true

横向模糊匹配

横向模糊指的是,一个正则可匹配的字符串的长度不是固定的,可以是多种情况的。
其实现的方式是使用量词。譬如 {m,n},表示连续出现最少 m 次,最多 n 次。

比如正则 /ab{2,5}c/ 表示匹配这样一个字符串:第一个字符是 “a”,接下来是 2 到 5 个字符 “b”,最后 是字符 “c”。
在这里插入图片描述
用于横向模糊匹配的量词:
在这里插入图片描述

var regex = "a{1,2}b{3,}c{4}d?e+f*/"

在这里插入图片描述

贪婪匹配

var regex = /\d{2,5}/g;
var string = "123 1234 12345 123456";
console.log( string.match(regex) ); 
// => ["123", "1234", "12345", "12345"]

其中正则 /\d{2,5}/,表示数字连续出现 2 到 5 次。会匹配 2 位、3 位、4 位、5 位连续数字。
但是其是贪婪的,它会尽可能多的匹配。你能给我 6 个,我就要 5 个。你能给我 3 个,我就要 3 个。 反正只要在能力范围内,越多越好。

惰性匹配

var regex = /\d{2,5}?/g; 
var string = "123 1234 12345 123456"; 
console.log( string.match(regex) ); 
// => ["12", "12", "34", "12", "34", "12", "34", "56"]

其中 /g 是全局匹配
其中 /\d{2,5}?/ 表示,虽然 2 到 5 次都行,当 2 个就够的时候,就不再往下尝试了。
在这里插入图片描述

var regex = /a{1,2}?b{3,}?c{4}?d??e+?f*?

在这里插入图片描述

纵向模糊匹配

纵向模糊指的是,一个正则匹配的字符串,具体到某一位字符时,它可以不是某个确定的字符,可以有多种 可能。
其实现的方式是使用字符组。譬如 [abc],表示该字符是可以字符 “a”、“b”、“c” 中的任何一个。
比如 /a[123]b/ 可以匹配如下三种字符串: “a1b”、“a2b”、“a3b”。
在这里插入图片描述

字符组

需要注意的是,字符组是匹配“组”中的一个字符
例如:[abc],表示匹配一个字符,它可以是"a",“b”,"c"之一。

连字符

如果字符的可能性非常多的情况下,可以使用范围表示法。【字符组的简写形式】
例如:[123456abcdefGHIJKLM],可以写成[1-6a-fG-M]。用连字符 - 来省略和简写。
注意:
因为连字符有特殊用途,那么要匹配 “a”、"-"、“z” 这三者中任意一个字符,该怎么做呢?
不能写成 [a-z],因为其表示小写字符中的任何一个字符。
可以写成如下的方式:[-az] 或 [az-] 或 [a-z]。
即要么放在开头,要么放在结尾,要么转义。总之不会让引擎认为是范围表示法就行了。

排除字符

纵向模糊匹配,还有一种情形就是,某位字符可以是任何东西,但就不能是 “a”、“b”、“c”。
此时就是排除字符组(反义字符组)的概念。例如 [^abc],表示是一个除 “a”、“b”、"c"之外的任意一个字 符。字符组的第一位放 ^(脱字符),表示求反的概念。
当然,也有相应的范围表示法。

常见的简写形式

在这里插入图片描述
如果要匹配任意字符怎么办?可以使用 [\d\D]、[\w\W]、[\s\S] 和 [^] 中任何的一个。

多选分支

一个模式可以实现横向和纵向模糊匹配。而多选分支可以支持多个子模式任选其一。
具体形式如下:(p1|p2|p3),其中 p1、p2 和 p3 是子模式,用 |(管道符)分隔,表示其中任何之一。
例如要匹配字符串 “good” 和 “nice” 可以使用 /good|nice/。
在这里插入图片描述

var regex = /good|nice/g; 
var string = "good idea, nice try.";
console.log( string.match(regex) );
// => ["good", "nice"]

而把正则改成 /goodbye|good/,结果是:

var regex = /goodbye|good/g;
var string = "goodbye"; 
console.log( string.match(regex) );
// => ["goodbye"]

也就是说,分支结构也是惰性的,即当前面的匹配上了,后面的就不再尝试了。

总结

下面举两个小案例
匹配字符,无非就是字符组、量词和分支结构的组合使用罢了。(正则并不是只有唯一写法)
要求匹配:

#ffbbad
#Fc01DF 
#FFF
#ffE

分析:
表示一个 16 进制字符,可以用字符组 [0-9a-fA-F]。
其中字符可以出现 3 或 6 次,需要是用量词和分支结构。
使用分支结构时,需要注意顺序。
正则如下:

var regex = /#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g; 
var string = "#ffbbad #Fc01DF #FFF #ffE";
console.log( string.match(regex) );
// => ["#ffbbad", "#Fc01DF", "#FFF", "#ffE"]

其可视化形式:
在这里插入图片描述
需求2:使用过mavonEditor的应该遇到过的一个需求,它是一个前端markdown插件,可以将文字图片转化为html字符串存入后端,但是取出来的时候正常显示到markdown的编辑页面,有些困难。
我做过的尝试:将markdown转的html字符串和正常编辑时的字符串在数据库中存两份,前端显示取一份,编辑的时候使用另一份。功能是实现了,就是有点占内存。于是,我尝试使用正则表达式将两份字符串进行转化:
类比案例如下:保留html中的标签就,将其他标签中的文字提取出来:

var html = "<div>" +
   "<p>你好呀</p>" +
   "<p>nifdkslafjkdlsa</p>" +
   "<img src='图片地址1' alt=''>" +
   "<p>1223323333</p>" +
   "<img src='图片地址2'>" +
   "</div>";
   / 替换
 var output = html.replace(/<(?!\/?br\/?.+?>|\/?img.+?>)[^<>]*>/gi, "");
 console.log(output);//你好呀nifdkslafjkdlsa<img src='图片地址1' alt=''>1223323333<img src='图片地址2'>

这个正则借鉴于: 传送门

本文摘自“老姚正则表达式迷你书”

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值