资讯专栏INFORMATION COLUMN

看完你就会正则表达式了

Anshiii / 1279人阅读

摘要:字符串对象的方法返回替换后的值常用于消除首尾空格方法的第二个参数可以使用美元符号来指代所替换的内容指代匹配的子字符串。与的区别在于当正则表达式加了标识符时,结果不同。

出场

为了匹配规定模式的文本
为了守护世界的和平
我们是穿梭在银河的正则表达式
就是这样~喵~

好用的正则表达式可视化工具: https://regexper.com/

语法
//字面量
var regExp1 = /pattern/flags;

//或用构造函数
var regExp2 = new RegExp(pattern[, flags]);

pattern:正则表达式的匹配模式
flags:可选,正则表达式的标识,也可选多个。g全局匹配,i忽略大小写,m匹配多行

一颗超简单的栗子:

var regExp = /abc/;
"abcdefg".replace(regExp, "WOW"); // "WOWdefg"
常用特殊字符 1.字符集合
字符 举例 含义
[] [xyz] xyz中任意一个字符 等价于[x-z]
[^] [^xyz] 匹配任意不在xyz中的一个字符,等价于[^x-z] (注意与^x区分,后者表示匹配以x开头的字符)
[-] [1-3] 匹配123中的任意一个字符,等价于[123]。注意:连字符只有出现在方括号中才表示连续的字符序列。
2.预定义模式

预定义模式就是某些常用模式的简写。

字符 含义
. 除 和 之外的任意字符,等价于[^ ]
d 数字0-9,等价于[0-9]
D 非数字字符,等价于[^0-9]
w 字母数字下划线,等价于[A-Za-z0-9_]
W 非字母数字下划线,等价于[^A-Za-z0-9_]
s 空白符
S 非空白符
换行符
3.需要转义的字符

正则模式中,需要用斜杠转义的:

* + ? $ ^ . |  ( ) { } [ ]

需要特别注意的是,如果使用RegExp方法生成正则对象,转义需要使用两个斜杠,因为字符串内部会先转义一次。

4.边界
字符 举例 含义
^ ^a 以a开头(注意与[^]区分,后者表示匹配不在[^]中的元素)
$ a$ 以a结尾
 smart,smart 单词边界,即[A-Za-z0-9_]之外的字符
B Bsmart 非单词边界

举个栗子说  和 B :

"You are smart, but she is smarter.".replace(/smart/,"kind");
//"You are kind, but she is smarter."

"You are smart, but she is smarter.".replace(/smartB/,"kind");
//"You are smart, but she is kinder."

if(不懂){ 就置几动手试试吧 (ง •̀_•́)ง }

5.数量词
字符 含义
? 匹配前面的模式 0或1次 {0,1}
* 匹配前面的模式 0或多次 {0,}
+ 匹配前面的模式 1或多次 {1,}
{n} 匹配前面的模式 n次
{n,} 匹配前面的模式 至少n次
{n,m} 匹配前面的模式 至少n次,至多m次
{0,m} 匹配前面的模式 至多m次
x(?=y) 只有x后面紧跟着y时,才匹配x,但是y不是匹配结果的一部分。例如/smart(?=girl)/只有后面有girl时,才匹配smart,但是girl不是匹配结果的一部分。
x(?!y) 只有x后面不紧跟着y时,才匹配x。例如/d+(?!.)/只有一个数字后面没有紧跟着小数点时才会匹配该数字,/d+(?!.)/.exec("3.141")匹配结果是141
6.贪婪与懒惰(非贪婪)

默认是贪婪模式匹配,即匹配尽可能多的字符。

var regExp1 = /d{3,6}/;
"1234567890".replace(regExp1, "X");
//"X7890"

若想手动开启懒惰模式,需要在模式后加 ?

var regExp1 = /d{3,6}?/;
"1234567890".replace(regExp1, "X");
//"X4567890"
7.分组与反向引用

分组又叫“子表达式”,把完整的正则表达式分成一个个小组,然后反过来用“组号”去引用这些小组就叫“反向引用”。

用例子来说:

//无分组
var regExp1 = /abc{2}/; //这样量词{2}只能匹配到c一个字符

//分组
var regExp2 = /(abc){2}/; //这样量词{2}就可以匹配到abc三个字符啦 
//同时 abc 也有了一个组号 $1

再看一个栗子:

var reg = /(d{1}).*(d{2}).*(d{3})/;
"1sss23sss456".replace(reg,"$1?$2?$3");
//"1?23?456"

上面的栗子换一种使用分组的方式:

var reg = /(d{1}).*(d{2}).*(d{3})/;
var result = reg.exec("1sss23sss456");
console.log(result[1]+"-"+result[2]+"-"+result[3]);
//"1-23-456"

组匹配非常有用,下面是一个匹配网页标签的例子:

var tagName = /<([^>]+)>[^<]*/; // 1 就是第一个组匹配的内容
tagName.exec("bold")[1]

上面代码稍加修改,就可以捕获带有属性的标签:

var html = "Helloworld";
var tag = /<(w+)([^>]*)>(.*?)/g;

var match = tag.exec(html);

match[1] // "b"
match[2] // " class="hello""
match[3] // "Hello"

match = tag.exec(html);

match[1] // "i"
match[2] // ""
match[3] // "world"

非捕获组: (?:x) 表示不返回该组匹配的内容,即匹配的结果中不出现这个括号。

常用方法 正则对象的方法 1.RegExp.prototype.test()

测试当前正则是否能匹配目标字符串,返回布尔值。

var reg = /d{2}/;
var str = "1sss23sss456";
reg.test(str); //true
2.RegExp.prototype.exec()

在目标字符串中执行一次正则匹配操作,返回匹配的子字符串。

var reg = /d{2}/;
var str = "1sss23sss456";
var result = reg.exec(str); 
result[0]; //23
result.index; //4
result.input; //"1sss23sss456"
3.RegExp.prototype.toString()

返回一个字符串,其值为该正则对象的字面量形式。覆盖了Object.prototype.toString() 方法。

var reg = /d{2}/;
reg.toString(); // "/d{2}/"
字符串对象的方法 1. str.replace()

返回替换后的值

var reg = /d{2}/;
var str = "1sss23sss456";
str.replace(reg,"?"); //"1sss?sss456"

常用于消除首尾空格:

var str = "  abc def ggg   ";
str.replace(/^s+|s+$/g, "");
// "abc def ggg"

replace方法的第二个参数可以使用美元符号来指代所替换的内容:

> $& 指代匹配的子字符串。
> $` 指代匹配结果前面的文本。
> $" 指代匹配结果后面的文本。
> $n 指代匹配成功的第n组内容,n是从1开始的自然数。
> $$ 指代美元符号$。

replace方法的第二个参数还可以是一个函数,将每一个匹配内容替换为函数的返回值。这个函数可以接受多个参数,第一个参数是捕捉到的内容,第二个参数开始是捕捉到的组匹配(有多少个组匹配,就对应有多少个参数)。此外,最后还可以添加两个参数,倒数第二个是捕捉到的内容在整个字符串中的位置,最后一个参数是原字符串。下面是一个网页模板替换的例子:

var prices = {
  "pr_1": "$1.99",
  "pr_2": "$7.99",
  "pr_3": "$9.99",
};

var template = "";

template.replace(
  /()()/, 
  function(match, p1, p2, p3 ,p4) {
    return p1 + p2 + p3 + prices[p2] + p4;
  });
//$1.99

注意:第二个分组要加 ? 开启懒惰模式,否则正则表达式默认的贪婪模式会匹配尽可能多的字符。贪婪模式下,上面的例子中第二个分组会匹配到pr_1">

exec()的区别在于:当正则表达式加了g标识符时,结果不同。看栗子:

var reg = /d{2}/g;
var str = "1sss23sss456";
reg.exec(str); //["23"]
str.match(reg); //["23","45"]
3.search()

返回匹配的首字符的位置。

var reg = /d{2}/;
var str = "1sss23sss456";
str.search(reg); //4
4.split()

返回分割后的数组。

var reg = /d{2}/;
var str = "1sss23sss456";
str.split(reg); //["1sss","sss","6"]
小练习

写一个匹配手机号的正则(第一位是1,第二位是[3,4,5,7,8]中的一个,后面还有9位数字)

写一个匹配 2017-01-01 或 2017/01/01 这两种格式日期的正则表达式

————答案:

/^1[34578]d{9}$/

/^d{4}[-/]d{2}[-/]d{2}$/

应用 1.使用正则改变数据结构
var re = /(w+)s(w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
console.log(newstr); //Smith, John
2.在多行中使用正则表达式
var s = "Please yes
make my day!";
s.match(/yes.*day/); // null
s.match(/yes[^]*day/); //"yes
make my day"
3.从URL中提取子域名
var url = "http://xxx.domain.com";
console.log(/[^.]+/.exec(url)[0]); //  "http://xxx"
console.log(/[^.]+/.exec(url)[0].substr(7)); //  "xxx"

匹配除了.之外的任意元素,一到多个字符。

“不会应用等于没有学会”,热烈欢迎小伙伴们在评论区补充平时用到正则表达式的地方,然后我会添加在文章里,一起收集吧 ヽ(•̀ω•́ )ゝ

参考:

1.正则表达式学习笔记

2.MDN RegExp文档

3.实战JS正则表达式

4.正则表达式30分钟入门教程

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82742.html

相关文章

  • 879本IT技术书籍(都看完你就可以升仙儿)

    摘要:珍藏版收集了好几年的书回过头来一看真不少拿过来跟你们一起分享下载链接我也会在官网上发布视频教程呀电影呀有用的资源你们懂得作者作者科技站长官网百度搜索科技博客公众号搜索 珍藏版---收集了好几年的书,回过头来一看,真不少,拿过来跟你们一起分享 showImg(https://img-blog.csdnimg.cn/20181123115931741.png?x-oss-process=i...

    用户83 评论0 收藏0
  • 879本IT技术书籍(都看完你就可以升仙儿)

    摘要:珍藏版收集了好几年的书回过头来一看真不少拿过来跟你们一起分享下载链接我也会在官网上发布视频教程呀电影呀有用的资源你们懂得作者作者科技站长官网百度搜索科技博客公众号搜索 珍藏版---收集了好几年的书,回过头来一看,真不少,拿过来跟你们一起分享 showImg(https://img-blog.csdnimg.cn/20181123115931741.png?x-oss-process=i...

    Kahn 评论0 收藏0
  • 879本IT技术书籍(都看完你就可以升仙儿)

    摘要:珍藏版收集了好几年的书回过头来一看真不少拿过来跟你们一起分享下载链接我也会在官网上发布视频教程呀电影呀有用的资源你们懂得作者作者科技站长官网百度搜索科技博客公众号搜索 珍藏版---收集了好几年的书,回过头来一看,真不少,拿过来跟你们一起分享 showImg(https://img-blog.csdnimg.cn/20181123115931741.png?x-oss-process=i...

    Airmusic 评论0 收藏0
  • 正则达式迷你书-笔记

    摘要:使用看完你就会正则表达式了四种操作验证切分提取替换第一章正则表达式字符匹配攻略正则表达式是匹配模式,要么匹配字符,要么匹配位置至少,至多匹配中的任一个字符范围表示法如果要匹配则要么要么要么通配符,表示几乎任意 API 使用 String#search String#split String#match String#replace RegExp#test Reg...

    IamDLY 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<