正则表达式

1、基础

1.1 含义:

通俗的来讲,正则表达式是一种匹配和替换的工具。如:在JS中验证手机号时,我们需要考虑用户输入的字符必须是number类型,且必须是11位的整数,且数字的前三位必须是134,155,183,188,199等等。对于这一问题,可以用if-else来实现,只不过太过于麻烦,而正则表达式就将这一问题简单化。

1.2 组成部分

一个完整的正则表达式由分隔符,表达式,修饰符三部分组成。
分隔符指的是除了特殊字符以外的任意字符
表达式指的是由一些特殊字符以及非特殊字符串组成
修饰符用于开启或关闭某些功能
举个例子:

let str = "1a2b3c4d5e6"
let reg = /[abcdef]/g
// 这里表示匹配abcdef这一类的字符,匹配成功就用-进行替换
console.log(str.replace(reg, '-')); // 1-2-3-4-5-6

其中,reg中的第一个/是分隔符,两个/之间的[abcef]是表达式,g是修饰符,表示全局匹配。常见的修饰符还有i表示忽略字母大小写,m表示多行搜索,搜索时识别换行符

1.3 语法

1、常见字符

字符 描述
[ABC] 匹配某类字符,如:[abc] 表示匹配某字符串中abc
^[ABC] 匹配某种字符之外的所有字符,如:[abc] 表示匹配某字符串中除abc之外的所有字符
[A-Z] 匹配所有大写字母
[a-z] 匹配所有小写字母
[\s] 匹配空白符,包括\f 换页符,\r 回车符,\t 水平制表符,\n 换行符,\x0b 垂直制表符等
[\S] 匹配非空白符
\w 匹配单词字符,包括数字,字母,下划线
\W 匹配非单词字符,除数字,字母,下划线之外的所有字符
.(点) 匹配除了回车符和换行符之外的所有字符
\d 匹配数字字符,等同于[0-9]
\D 匹配非数字字符,等同于^[0-9]

2、特殊字符和限定符

字符 描述
$ 匹配输入字符串的结尾位置
* 匹配前面的子表达式零次或多次
+ 匹配前面的子表达式一次或多次
? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符
^ 匹配输入字符串的开始位置
( ) 标记一个子表达式的开始和结束位置
| 指明两项之间的一个选择
{n} n 是一个非负整数。匹配确定的 n 次
{n,} n 是一个非负整数。至少匹配n 次
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次

注意:+ 和 *都是贪婪的,它们会尽可能多的匹配,只有在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配
举个例子:

  • do 能匹配 "d" 以及 "doo"。 等价于{0,}
  • 'do+' 能匹配 "do" 以及 "doo",但不能匹配 "d"。+ 等价于 {1,}
  • "do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 。? 等价于 {0,1}
  • 'o{2}' 不能匹配 "do" 中的 'o',但是能匹配 "food" 中的两个 o
  • 'o{2,}' 不能匹配 "do" 中的 'o',但是能匹配 "food" 中的两个 o以及"foood"中的3个o
  • 'o{2,5}' 不能匹配 "do" 中的 'o',但是能匹配 "food" 中的两个 o以及"foood"中的3个o以及"fooood"中的4个o

1.4 正则表达式对象

JavaScript中使用RegExp对象来封装一个正则表达式,并提供相关的方法和属性。有两种创建方法,分别如下:

  • 字面量创建方法
let reg = /\bis\b/g;  //表示全局匹配左右的单词边界为is的所有字符
let str = "He is a boy. This is a dog. Where is she?";
// 这里的3个is左右两边都有完整的单词,都会匹配。
console.log(str.replace(reg, "IS")); // He IS a boy. This IS a dog. Where IS she?
  • 构造函数创建方法
let reg = new RegExp("\\bis\\b", "g");
let str = "He is a boy. This is a dog. Where is she?";
console.log(str.replace(reg, "IS")); // He IS a boy. This IS a dog. Where IS she?

1.5 字符类

  • 一般情况下,正则表达式一个字符对应字符串的一个字符。
    例如:表达式 ab\t 的含义是 "ab"紧接着一个 tab(制表符)。
  • 当需要匹配一类字符时,可以使用[ ]来构造一个简单的类。
    所谓类,是指符合某些特性的对象,一个泛指,而不是特指某个字符。
    例如:表达式[abc]把字符 a、b、c 归位一类,表达式可以匹配这类字符,即匹配其中之一。如:

    let str = "a1b2c3d4";
    let reg = /[abc]/g // 表示全局匹配字符a,b,c
    console.log(str.replace(reg, "x")); // x1x2x3d4
  • 使用元字符\^创建反向类(负向类),即匹配不属于该类的字符。
    例如:[^abc]表示不是字符 a、b、c 其中之一的字符。如:

    let str = "a1b2c3d4";
    let reg = /[^abc]/g // 表示全局匹配字符a,b,c
    console.log(str.replace(reg, "x")); // axbxcxxx

1.6 范围类

  • 需要匹配数字时,可以使用范围类。
    例如:[a-z]表示从 a 到 z 之间的任意字符,且包含 a 和 z 本身。如:

    let str = "a1b2c3d4z0";
    console.log(str.replace(/[a-z]/g, "X")); //全局匹配所有的小写字母并替换成X,输出结果 X1X2X3X4X0
  • 在[ ]中可以将一些范围连续书写

    let str = "a1b2c3D5E6F7";
    console.log(str.replace(/[a-zA-Z0-9]/g, "*")); // 全局匹配大小写字幕和数字并替换成* 输出 ************
    str = "1998-09-19";
    console.log(str.replace(/[0-9-]/g, "0")); //全局匹配数字和下换线并替换成0 输出结果 0000000000

1.7 边界

字符 描述
^ 以 xxx 开始
$ 以 xxx 结束
\b 单词边界
\B 非单词边界

举个例子:

let str = "This is a boy";
console.log(str.replace(/is/g, "0")); // 全局匹配所有的is,输出Th0 0 a boy
console.log(str.replace(/\bis\b/g, "0")); // This 0 a boy
console.log(str.replace(/\Bis\b/g, "0"));// 全局匹配左边界不是完整单词右边界是单词的字符,输出Th0 is a boy
let str = "@123@abc@";
console.log(str.replace(/@./g, "Q")); // 全局匹配@以及后面跟任意字符的字符,输出Q23Qbc@
console.log(str.replace(/^@./g, "Q")); // 全局匹配以@开头以及后面跟任意字符的字符,输出Q23@abc
console.log(str.replace(/.@/g, "Q")); // 全局匹配任意字符后跟@的字符,输出@12QabQ
console.log(str.replace(/.@$/g, "Q")); // 全局匹配任意字符后跟以@结尾的字符,输出@123@abQ
str = `@123
@456
@789`;
console.log(str.replace(/^@\d/g, "X"));
/* 这里表示全局匹配以@开头的数字字符进行替换,因此输出:
X23
@456
@789 */
console.log(str.replace(/^@\d/gm, "X"));
/* 这里表示全局匹配,多行搜索以@开头的数字字符进行替换,因此输出:
X23
X56
X89 */

1.8 分组,或,反向引用,忽略分组

  • 分组()
let str = "a1b2c3d4"
console.log(str.replace(/[a-z]\d{3}/g, "X")); // 表示单独匹配3次小写字母和数字,输出a1b2c3d4
console.log(str.replace(/([a-z]\d){3}/g, "X")); // 表示匹配3次小写字母和数字组成的分组,输出Xd4
  • 或 |,表示左右字符二选一
console.log("ByronCasper".replace(/Byron|Casper/g, "X")); // 全局匹配Byron或者Casper并进行替换,输出XX
console.log("ByrCasperByronsper".replace(/Byr(on|Ca)sper/g, "X")); // 全局匹配Byronsper或者ByrCasper并进行替换,输出XX
  • 反向引用:使用$n的形式引用模式中分组匹配到的文本,n为索引,从1开始,如:把 2020-03-04 替换成 03/04/2020,代码如下:
// $n 反向引用
console.log("2020-03-04".replace(/(\d{4})-(\d{2})-(\d{2})/g, "$2/$3/$1")); // 表示先全局匹配4位数字-2位数字-2位数字各分组组成的字符串,再通过索引排序,并将-替换成/ 输出03/04/2020
  • 忽略分组:当不想捕获分组时,可以使用?:直接输出$n,如:
// 忽略分组
console.log("2020-03-04".replace(/(\d{4})-(\d{2})-(?:\d{2})/g, "$2/$3/$1")); // 03/$3/2020

1.9 前瞻

  • 前瞻分为正向前瞻exp(?=assert)和负向前瞻exp(?!assert)
  • exp 和 assert 都是正则表达式,匹配到 exp 时还要判断 assert 是否符合,如果符合才会被匹配。
    例如:表达式\w(?=\d),表示匹配到一个单词\w 时还需要向后判断是否为一个数字\d
console.log("a2*34V8".replace(/\w(?=\d)/g, "X")); // X2*X4X8
console.log("a2*34V8".replace(/\w(?!\d)/g, "X")); // aX*3XVX

2、JavaScript中的正则表达式

2.1 RegExp对象属性

global,是否全文搜索,默认 false。
ignoreCase,是否忽略大小写,默认 false。
multiline,是否多行搜索,默认 false。
lastIndex,当前表达式匹配内容的最后一个字符的下一个位置。
source,正则表达式的文本字符串。
举个例子:

let reg1 = /\w/;
let reg2 = /\w/gim;
console.log(reg1.global); // false
console.log(reg1.ignoreCase); // false
console.log(reg1.multiline); // false
console.log(reg2.global); // true
console.log(reg2.ignoreCase); // true
console.log(reg2.multiline); // true
//以上三个属性都是只读的。
console.log(reg2.source); // \w

2.2 RegExp对象方法

  • test(str),用于测试字符串参数中是否存在匹配正则表达式模式的字符串,返回 true 或 false。
  • exec(str),使用正则表达式模式对字符串执行搜索,并将更新全部 RegExp 对象的属性以反映匹配结果。
    • 如果没有匹配的文本则返回 null,否则会返回一个结果“数组”对象:
      [匹配到的文本, 与第 1 个分组相匹配的文本,与第 n 个分组相匹配的文本...]
    • index,声明匹配文本的第一个字符的位置
    • input,存放被检索的字符串 string

举个例子:

let reg1 = /\w{1,2}/g; // 表示1~2位单词字符(包括数字,字母,下换线)
console.log(reg1.test("ab,cd")); // ab,cd符合reg1的规则,输出true
console.log(reg1.exec("ab,cd")); // [ 'cd', index: 3, input: 'ab,cd', groups: undefined ]
console.log(reg1.source); // \w{1,2}

2.3 字符串正则方法

  • search(reg),用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。返回第一个匹配结果的 index,没有匹配到返回-1。不执行全局匹配。
  • match(reg),检索字符串以找到一个或多个与 regexp 匹配的文本,未找到返回 null,找到后返回一个数组。与 RegExp 的 exec()方法相同。
  • split(reg),利用 regexp 匹配结果作为分隔符对字符串进行分割,返回一个数组。
  • replace(reg, newStr),将 regexp 的匹配结果替换成 newStr,返回一个新字符串。
    举个例子:
let str = "<java> and <javascript> is deferent!";
console.log(str.match(/<\S*>/g)); // [ '<java>', '<javascript>' ]
console.log(str.replace(/<(\S*)>/g, "<<$1>>")); // <<java>> and <<javascript>> is deferent!
console.log(str.split(/[<>]/g)); // [ '', 'java', ' and ', 'javascript', ' is deferent!' ]

ES6学习笔记(七)正则表达式的更多相关文章

  1. ES6学习笔记七:生成器与异步操作

    一:Generator Generator 函数是一个普通函数,但是有两个特征.一是,function关键字与函数名之间有一个星号:二是,函数体内部使用yield表达式,输出不同的内部状态. 执行 G ...

  2. [Scala]Scala学习笔记七 正则表达式

    1. Regex对象 我们可以使用scala.util.matching.Regex类使用正则表达式.要构造一个Regex对象,使用String类的r方法即可: val numPattern = &q ...

  3. ES6学习笔记七Generator、Decorators

    Generator异步处理 { // genertaor基本定义,next()一步步执行 let tell=function* (){ yield 'a'; yield 'b'; return 'c' ...

  4. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

  5. Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  6. es6学习笔记-class之一概念

    前段时间复习了面向对象这一部分,其中提到在es6之前,Javasript是没有类的概念的,只从es6之后出现了类的概念和继承.于是乎,花时间学习一下class. 简介 JavaScript 语言中,生 ...

  7. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  8. ES6学习笔记<五> Module的操作——import、export、as

    import export 这两个家伙对应的就是es6自己的 module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成一个个功能相对独立但相互依赖的小 ...

  9. ES6学习笔记<四> default、rest、Multi-line Strings

    default 参数默认值 在实际开发 有时需要给一些参数默认值. 在ES6之前一般都这么处理参数默认值 function add(val_1,val_2){ val_1 = val_1 || 10; ...

  10. ES6学习笔记<三> 生成器函数与yield

    为什么要把这个内容拿出来单独做一篇学习笔记? 生成器函数比较重要,相对不是很容易理解,单独做一篇笔记详细聊一聊生成器函数. 标题为什么是生成器函数与yield? 生成器函数类似其他服务器端语音中的接口 ...

随机推荐

  1. Excel 统计函数(一):SUMIF 和 SUMIFS

    SUMIF [语法]SUMIF(range, criteria, [sum_range]). [参数] range :求和范围 criteria :筛选的条件 sum_range :可选参数,实际的求 ...

  2. NC202475 树上子链

    题目链接 题目 题目描述 给定一棵树 T ,树 T 上每个点都有一个权值. 定义一颗树的子链的大小为:这个子链上所有结点的权值和 . 请在树 T 中找出一条最大的子链并输出. 输入描述 第一行输入一个 ...

  3. 【java】学习路径45-多线程-线程生命周期

    线程分为五大状态:新建.就绪.运行.阻塞.死亡. New,Runnable,Running,Blocked,Terminated. 新建状态(New: 创建好一个系统对象,在调用start()之前,线 ...

  4. Linux网桥配置(用于大数据虚拟化)

    理解 VMware里面有三个虚拟机,分别为RHEL8,RHEL7,Windows的虚拟机,只有一个物理网卡连接物理网络,现在三台虚拟机都需要直连到物理网络,此时无法访问物理网络,只能给一个虚拟机访问物 ...

  5. 开发个RTMP播放器居然这么难?RTMP播放器对标和考察指标

    好多开发者提到,RTMP播放器,不知道有哪些对标和考察指标,以下大概聊聊我们的一点经验,感兴趣的,可以关注 github: 1. 低延迟:大多数RTMP的播放都面向直播场景,如果延迟过大,严重影响体验 ...

  6. KFS replicator安装(KES-KES)

    源端 一.安装前置配置 1.创建安装用户 groupadd flysync useradd flysync -g flysync -G kingbase passwd flysync 2.上传安装文件 ...

  7. 放弃 Electron,拥抱 WebView2!JavaScript 快速开发独立 EXE 程序

    Electron 不错,但也不是完美的. Electron 带来了很多优秀的桌面软件,但并不一定总是适合我们的需求. 多个选择总是好事! 我使用 Electron 遇到的一些麻烦 1.Electron ...

  8. Go语言学习的坑爹历程

    鄙人暑期实习,需要用Go语言进行编程 在go语言中,结构体的定义只支持变量的声明,成员函数是采用"接口方法"来实现的 留一个成员定义的模板在此 package main impor ...

  9. vue3+three.js实现疫情可视化

    前言 自成都九月份以来疫情原因被封了一两周,居家着实无聊,每天都是盯着微信公众号发布的疫情数据看,那种页面,就我一个前端仔来说,看着是真的丑啊!(⊙_⊙)?既然丑,那就自己动手开整!项目是2022.9 ...

  10. Git Rebase-提交整洁之道

    git rebase git rebase是一个非常有用的命令,但知道和用的人非常少,今天介绍一下其作用 git rebase -i 作用:常用来合并多个相同目的的提交. 交互式有下面几个命令,常用命 ...