【JavaScript】正则表达式详解

news2024/11/15 3:24:24

💻【JavaScript】正则表达式🏠专栏:JavaScript
👀个人主页:繁星学编程🍁
🧑个人简介:一个不断提高自我的平凡人🚀
🔊分享方向:目前主攻前端,其他知识也会阶段性分享🍀
👊格言:☀️没有走不通的路,只有不敢走的人!☀️
👉让我们一起进步,一起成为更好的自己!!!🎁

文章目录

  • 【JavaScript】正则表达式
    • 一. 什么是正则表达式?
    • 二. 创建正则表达式
    • 三. 正则表达式修饰符
    • 四. 正则表达式的方法
      • (1) test()
      • (2) search()
      • (3) replace()
      • (4) exec()
      • (5) match()
      • (6) split()
    • 五. 正则表达式模式
      • (1) 方括号
      • (2) 元字符
      • (3) 量词
      • (4) 正则语法
      • (5) 重复元字符
      • (6) 正则的捕获方式
    • 六. ES9新特性(正则扩展)
      • (1) 命名捕获分组
      • (2) 反向断言
      • (3) dotAll 模式
    • 七. 案例

【JavaScript】正则表达式

正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。

一. 什么是正则表达式?

正则表达式是由一个字符序列形成的搜索模式。
当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容。
正则表达式可以是一个简单的字符,或一个更复杂的模式。
正则表达式可用于所有文本搜索和文本替换的操作。

正则的两大特性

  1. 懒惰

    每次捕获的时候都会从字符串[0]开始检索
    解决:给正则添加标识符g

  2. 贪婪

    每次在捕获内容的时候,尽可能多的去捕获内容
    解决:使用非贪婪限定符(在原来的限定符后面加一个?)

// 贪婪捕获
var str = '1234567abcd'
var reg = /\d*/
console.log(reg.exec(str)); // ['1234567', index: 0, input: '1234567abcd', groups: undefined]

贪婪限定符:(*、+、?、{n,}、{n,m})

// 贪婪限定符
var reg = /<div.*>/
console.log(reg.exec(str)); // '<div class="box" id="box"><span></span></div>'

非贪婪限定符:(*?、+?、??、{n,}?、{n,m}?)

// 非贪婪限定符
var reg = /<div.*?>/
console.log(reg.exec(str)); // '<div class="box" id="box">'

二. 创建正则表达式

(1) 内置构造函数方式创建

var reg = new RegExp("正则","匹配模式");
// eg:
var reg = new RegExp('abcd', 'ig');
console.log(reg.test('abCD')); // true

(2) 字面量方式创建

var reg = /正则表达式/匹配模式
// eg:
var reg = /abcd/ig;
console.log(reg.test('abCD')); // true

在构造函数中可以传递一个匹配模式作为第二个参数。

语法:

var 变量 = /正则表达式/匹配模式
//使用构造函数创建正则表达式
var a = new RegExp("a","i");
//使用字面量创建正则表达式
var reg = /a/i
console.log(typeof reg);//typeof 用于检查正则对象,会返回object
console.log(reg.test("Abc"))//结果:true

三. 正则表达式修饰符

修饰符 可以在全局搜索中不区分大小写:

i(ignore case):忽略大小写
g(global):执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)
m(multiple lines):执行多行匹配

设置匹配模式时,可以都不设置,也可以设置1个,也可以全设置,设置时没有顺序要求。

四. 正则表达式的方法

(1) test()

test() 方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。

语法:正则表达式.test(字符串)

var a = new RegExp("e");//检查下列句子中是否含有e
document.write(a.test("There is a good thing"));
<!-- 结果:true -->

(2) search()

search() 方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,并$\color{red} {返回子串的起始位置} $。

语法:字符串.search(正则表达式)

实例:使用正则表达式搜索 “Root” 字符串,且不区分大小写:

var str = "Visit Root!"; 
var n = str.search(/Root/i);

输出结果:6

(3) replace()

replace() 方法用于在字符串中用一些字符串替换另一些字符串,或替换一个与正则表达式匹配的子串。

实例

使用正则表达式且不区分大小写将字符串中的 Cat 替换为 Root:

var str = "Visit Cat !";
var txt = str.replace(/cat/i,"Root");

结果输出为:

Visit Root !

// eg: 
// 批量替换敏感词
var arr = ['HH', 'MM', 'NN']
var str = 'aHHdfasMMdfaNNdsfaNNsNNdffas'
var reg = new RegExp(arr.join("|"), "g")
console.log(str.replace(reg, '**')); // a**dfas**dfa**dsfa**s**dffas

(4) exec()

exec() 方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null。

语法:正则表达式.exec(字符串)

var reg=/\d/;  
var str="ab56efg";
var res=reg.exec(str);
console.log(res);//返回一个数组,内容是4
//字符串中满足正则表达式的部分提取出来
//遇到满足条件的就返回,所以只返回4

(5) match()

match() 方法检索返回一个字符串匹配正则表达式的结果。

语法:字符串.match(正则表达式)

var reg=/[a-z]/g;
var str="ab56efg";
var res=str.match(reg); //字符串中满足表达式的部分提取出来
console.log(res);//结果:a,b,e,f,g

区别: 正则表达式.exec(字符串),正则表达式提供的方法 字符串.match(正则表达式) 字符串的方法
相同: 都返回一个数组,只要匹配到符合规则的数据就返回

(6) split()

将一个字符串拆分为一个数组

语法:字符串.match(正则表达式/字符串)

var str = "1j1j1k2d7o";
var result = str.split("k");
console.log(result);
//结果:"1j1j1,2d7o"
var result = str.split(/[A-z]/);
console.log(result);
//结果:"1,1,1,2,7"

五. 正则表达式模式

(1) 方括号

方括号用于查找某个范围内的字符:

表达式描述
[abc]查找方括号之间的任何字符。
[0-9]查找任何从 0 至 9 的数字。
(x|y)查找任何以 | 分隔的选项。

(2) 元字符

元字符(Metacharacter)是拥有特殊含义的字符:

元字符描述
.(小数点)默认匹配除换行符之外的任何单个字符。
\w匹配一个单字字符(字母、数字或者下划线)。等价于 [A-Za-z0-9_]
\W匹配一个非单字字符。等价于 [^A-Za-z0-9_]
\d查找数字(至少含有一个数字(0~9))
\D查找非数字字符(至少含有一个非数字)
\s查找空白字符(至少含有一个空白字符(空格、缩进、\b…))
\S查找非空白字符(至少含有一个不是空白字符)
\b匹配单词边界
\B匹配非单词边界
\0查找NUL字符
\n查找换行符
\f查找换页符
\r查找回车符
\t查找制表符
\v查找垂直制表符
\xxx查找以八进制 xxx 规定的字符
\xdd查找以十六进制 dd 规定的字符
\uxxxx查找以十六进制 xxxx 规定的 Unicode 字符

实例

var reg = /\W/  //true
console.log(reg.test("!@#!"))
var reg = /\D/  //false
console.log(reg.test("123"))
var reg = /\bchild\b/  //false
console.log(reg.test("hello children"))

(3) 量词

量词描述
?出现0次或一次
+出现一次或多次
*出现0次或多次
{n}出现n次
{n,m}出现n到m次
{n,}至少出现n次

实例

var reg = /a{3}/;//判断a是否连续出现3次
console.log(reg.test("aaabc"));//true
console.log(reg.test("abc"));//false
var reg = /(ab){3}/;//判断ab是否连续出现3次
console.log(reg.test("abababc"));//true
console.log(reg.test("abc"));//false
var reg = /ab{1,3}c/;//判断b是否连续出现1-3次
console.log(reg.test("abbbc"));//true
console.log(reg.test("abbbbbc"));//false
console.log(reg.test("bac"));//false

(4) 正则语法

正则描述
|
[ ]
[^ ]除了
[a-z]小写字母
[A-Z]大写字母
[A-z]任意字母
^开头
$结尾

实例:

//检查字符串中是否含有a或b
var reg = /a|b/
console.log(reg.test("bcd"))//结果:true
//检查字符串中是否含有字母
var reg = /[a-z]/
console.log(reg.test("bcdfsji"))//结果:true
//检查字符串中是否含有abd或abc或abf
var reg = /ab[cdf]/
console.log(reg.test("bcabcji"))//结果:true
//检查一个字符串是否以a结尾
var reg = /a$/
console.log(reg.test("bcabcjia"))//结果:true
//如果在正则表达式中同时使用^ $则要求必须完全符合正则表达式
var reg = /^a$/
console.log(reg.test("as"))//结果:false

(5) 重复元字符

符号: \数字

作用: 表示重复第n个小括号的内容,要求和第n个小括号的内容一模一样

// 表示这个()里面的整体内容出现2次就可以。不要求一模一样
// var reg1 = /^(abc|def){2}$/

// 表示 \1 位置 需要出现一个 和 第一个 小括号 一模一样的内容
var reg1 = /^(abc|def)\1$/
console.log(reg.test('abcabc')); // true
console.log(reg.test('defdef')); // true
console.log(reg.test('abcdef')); // false

var reg2 = /^(abc|def)(哈哈|嘻嘻)\2$/
console.log(reg.test('abc哈哈哈哈')); // true
console.log(reg.test('abc哈哈嘻嘻')); // false
console.log(reg.test('abc嘻嘻嘻嘻')); // true

(6) 正则的捕获方式

语法:正则表达式.exec(字符串)
作用:始字符串中捕获到符合正则规则的字符串片段

返回值

  1. 当原始字符串没有符合规则的时候,返回null

  2. 当原始字符串由符合规则的片段的时候:

    返回值必然是一个数组,数组的[0] 是捕获出来的字符串片段

    • 没有(), 没有g

      不管写多少次,只能捕获第一组匹配规则的字符串片段

      var reg = /\d{3}/
      var str = 'adfa123sals456hdfl789kasakhdf012'
      var res = reg.exec(str)
      console.log(res); // ['123', index: 4, input: 'adfa123sals456hdfl789kasakhdf012', groups: undefined]
      console.log(reg.exec(str)); // ['123', index: 4, input: 'adfa123sals456hdfl789kasakhdf012', groups: undefined]
      console.log(reg.exec(str)); // ['123', index: 4, input: 'adfa123sals456hdfl789kasakhdf012', groups: undefined]
      
    • 有()

      会在返回值数组的[1]开始,依次是每一个()中单独的内容

      var reg = /(\d{2})(\d{2})(\d{2})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|x)/
      var str = '22230120050101123x'
      console.log(reg.exec(str));
      // ['22230120050101123x', '22', '23', '01', '2005', '01', '01', '12', '3', 'x', index: 0, input: '22230120050101123x', groups: undefined]
      
    • 有g

      g 叫做全局标识符

      第二次捕获开始会从第一次捕获的结束为止开始检索

      直到找不到内容,返回null

      var reg = /\d{3}/g 
      var str = 'adfa123sals456hdfl789kasakhdf012'
      console.log(reg.exec(str)); // ['123', index: 4, input: 'adfa123sals456hdfl789kasakhdf012', groups: undefined]
      console.log(reg.exec(str)); // ['456', index: 11, input: 'adfa123sals456hdfl789kasakhdf012', groups: undefined]
      console.log(reg.exec(str)); // ['789', index: 18, input: 'adfa123sals456hdfl789kasakhdf012', groups: undefined]
      

匹配但是不捕获

当我们需要使用()这个整体作用,但是不需要把()里面的内容单独捕获的时候:可以书写(?😃

六. ES9新特性(正则扩展)

(1) 命名捕获分组

捕获:对正则匹配的数据进行(.*)单独提取。

// 正则扩展:命名捕获分组 
// 声明一个字符串 
let str = '<a href="http://www.baidu.com">你好</a>'; 
// 需求:提取url和标签内文本 
// 之前的写法 
const reg = /<a href="(.*)">(.*)<\/a>/; 
// 执行 
const result = reg.exec(str); 
console.log(result); 
// 结果是一个数组,第一个元素是所匹配的所有字符串 
// 第二个元素是第一个(.*)匹配到的字符串 
// 第三个元素是第二个(.*)匹配到的字符串 
// 我们将此称之为捕获 
console.log(result[1]); 
console.log(result[2]); 
const reg1 = /<a href="(?<url>.*)">(?<text>.*)<\/a>/; 
const result1 = reg1.exec(str); console.log(result1); 
// 这里的结果多了一个groups 
// groups: 
// text:"你好" 
// url:"http://www.baidu.com" 
console.log(result1.groups.url); 
console.log(result1.groups.text); 

结果:

请添加图片描述

(2) 反向断言

断言:判断这次的匹配结果是否正确

正向断言/反向断言 做一个唯一性的识别
正向断言(目标的后面)

let str = "JS314你知道么5呀"; 
// 需求:我们只想匹配到5 
// 正向断言 
const reg = /\d+(?=啦)/; 
// 前面是数字后面是啦 
const result = reg.exec(str); 

结果:

请添加图片描述

反向断言(目标的前面)

// 反向断言 
const reg1 = /(?<=么)\d+/; 
// 后面是数字前面是么 
const result1 = reg.exec(str); 
console.log(result1); 

结果:

请添加图片描述

(3) dotAll 模式

dot就是. 元字符,表示除换行符之外的任意单个字符

之前的写法:

let str = `
<ul>
    <li>
        <a href="#">a</a>
        <p>b</p>
    </li>
    <li>
        <a href="#">c</a>
        <p>d</p>
    </li>
</ul>
`;
const reg = /<li>\s+<a href="#">(.*?)<\/a>\s+<p>(.*?)<\/p>/;
console.log(reg.exec(str));

结果:
请添加图片描述

使用dotAll后:

let str = `
<ul>
    <li>
        <a href="#">a</a>
        <p>b</p>
    </li>
    <li>
        <a href="#">c</a>
        <p>d</p>
    </li>
</ul>
`;
// const reg = /<li>\s+<a href="#">(.*?)<\/a>\s+<p>(.*?)<\/p>/g;
const reg = /<li>.*?<a href="#">(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;
// console.log(reg.exec(str));
let result;
while ((result = reg.exec(str))) console.log(result);

g为全局匹配 匹配不到是返回null,结束循环

结果:

请添加图片描述

七. 案例

案例一:书写正则验证用户名

规则

  • 6 ~ 12 位
  • 只能包含数字字母下划线 \w
  • 不能以 下划线开头
var reg = /^[0-9a-zA-Z]\w{5,11}$/

案例二:书写正则验证邮箱

规则

  • @ 前面, 和用户名规则一致
  • 邮箱类型只接受 163 qq sina
  • 后缀只接受 com cn
var reg = /^[0-9a-zA-Z]\w{5,11}@(163|qq|sina)\.(com|cn)$/

案例三:书写正则验证手机号

规则

  • 前面有可能带有 +86 有可能没有 ? {0,1}
  • +86 和 电话号之间有可能有空格有可能没有
  • 号段只接受 133 135 188
var reg = /^(\+86 ?)?(133|135|188)\d{8}$/

案例四:书写正则验证 0 ~ 255 的数字

var reg = /^(\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])$/
<!-- 验证:0 ~ 666 -->
var reg = /^(\d{1,2}|[1-5]\d{2}|6[0-5]\d|66[0-6])$/

结束语

希望对您有一点点帮助,如有错误欢迎小伙伴指正。
👍点赞:您的赞赏是我前进的动力!
⭐收藏:您的支持我是创作的源泉!
✍评论:您的建议是我改进的良药!
一起加油!!!💪💪💪

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/177032.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL(五):事务简介、事务的特性、事务的概念及状态、支持事务的引擎

目录一、事务的起源二、事务的特性2.1 原子性(Atomicity)2.2 隔离性(Isolation)2.3 一致性(Consistency)2.4 持久性(Durability)三、事务的概念及状态四、支持事务的引擎一、事务的起源 事务源于日常生活中的业务&#xff0c;现有这样的一个场景&#xff0c;A账户有11元&#…

人工智能学习06--pytorch04--transforms

transforms主要对图片进行一些变换 transform该如何使用&#xff08;python&#xff09; 从transform中选择一个class&#xff0c;进行创建 依据创建的工具看需要什么&#xff08;如img&#xff09; 为什么需要tensor的数据类型 tensor数据类型&#xff1a;包装了神经网络…

opencv win10 4.7.0 源码编译 vs2019 cmake

下载opencv & opencv-contrib 4.7.0源码&#xff1b;注意下载地址https://github.com/opencv/opencv/releases https://github.com/opencv/opencv_contrib/releases/tag/4.7.0 版本要一模一样cmake输出文件夹为&#xff1a;opencv-4.7.0-build 遇到下载问题如下&#xf…

常见递归模式

常见递归模式递归模式遍历二叉树模式回溯模式子问题分解模式递归模式 常见递归模式&#xff1a; 遍历二叉树模式回溯模式子问题分解模式 遍历二叉树模式 只要涉及递归的问题&#xff0c;都是树的问题&#xff0c;或者说树的遍历。 void traverse(TreeNode root) { // 遍历…

混合背包问题

混合背包问题一、问题二、分析三、代码一、问题 二、分析 混合背包问题就是将我们之前讲过的01背包&#xff0c;完全背包&#xff0c;分组背包&#xff0c;多重背包问题等等中的任意几个混合在一起。因此想要解决这个问题&#xff0c;就需要对01背包&#xff0c;完全背包&…

PDF划词翻译软件

PDF划词翻译 一个简单的PDF划词翻译软件。 Github仓库地址&#xff1a;https://github.com/WCX1024979076/simple_pdf_translator Github下载地址&#xff1a; https://github.com/WCX1024979076/simple_pdf_translator/releases/tag/v0.1.0 Gitee仓库地址&#xff1a; htt…

ROS2机器人编程简述humble-第三章-COMPUTATION GRAPH .2

ROS2机器人编程简述humble-第三章-PERCEPTION AND ACTUATION MODELS .1避开障碍物计算图如何呢&#xff1f;该应用程序的计算图非常简单&#xff1a;订阅激光主题的节点向机器人发布速度命令。控制逻辑解释&#xff1a;输入的感知信息并产生控制命令&#xff08;输出&#xff0…

深度学习:DenseNet思想总结

深度学习&#xff1a;DenseNet思想总结前言DenseNetResNetDense connectionComposite functionPooling layersGrowth rateBottleneck layersCompressionImplementation Details总结前言 论文中提出的架构为了确保网络层之间的最大信息流&#xff0c;将所有层直接彼此连接。为了…

JUC面试(八)——阻塞队列

阻塞队列 队列&#xff0c;FIFO BlockingQueue 阻塞队列&#xff0c;排队拥堵&#xff0c;首先它是一个队列&#xff0c;而一个阻塞队列在数据结构中所起的作用大致如下图所示&#xff1a; 线程1往阻塞队列中添加元素&#xff0c;而线程2从阻塞队列中移除元素 当阻塞队列是空…

Java基础(程序流程控制)

程序流程控制1..顺序结构程序从上到下逐行执行&#xff0c;中间没有判断和跳转2.分支结构根据条件&#xff0c;选择性执行某段代码有if-else和switch-case两种分支需要注意根据相应的方法&#xff0c;来输入指定类型的值。如果不匹配则会异常&#xff1a;InputMisMatchExceptio…

结构型模式-桥接模式

1.概述 现在有一个需求&#xff0c;需要创建不同的图形&#xff0c;并且每个图形都有可能会有不同的颜色。我们可以利用继承的方式来设计类的关系&#xff1a; 我们可以发现有很多的类&#xff0c;假如我们再增加一个形状或再增加一种颜色&#xff0c;就需要创建更多的类。试…

2.5总线标准

文章目录一、引子二、总线标准1.基本概念2.总线标准&#xff08;1&#xff09;系统总线①ISA②EISA扩展总线③拓展&#xff08;2&#xff09;局部总线①VESA②PCI③AGP④PCI-E&#xff08;3&#xff09;设备总线①RS-232C②SCSI③PCMCIA④USB3.连接硬盘总线标准①IDE②SATA三、…

JAVA 服务内存占用太高

一、问题现象 某天&#xff0c;运维老哥突然找我&#xff1a;“你们的某 JAVA 服务内存占用太高&#xff0c;告警了&#xff01;GC 后也没释放&#xff0c;内存只增不减&#xff0c;是不是内存泄漏了&#xff01;” 然后我赶紧看了下监控&#xff0c;一切正常&#xff0c;距离上…

redis缓存问题引进

1、缓存使用 为了系统性能的提升&#xff0c;我们一般都会将部分数据放入缓存中&#xff0c;加速访问。而 db 承担数据落 盘工作。 哪些数据适合放入缓存&#xff1f;  即时性、数据一致性要求不高的  访问量大且更新频率不高的数据&#xff08;读多&#xff0c;写少&…

BigDecimal BigInteger的使用

1、BigDiCemal 【问题】在项目中&#xff0c;我们进行计算的时候&#xff0c;有时候需要考虑 四舍五入&#xff0c;精度丢失的问题&#xff0c;面对这种问题&#xff0c;我们应该怎么处理&#xff1f; System.out.println(0.20.1);System.out.println(0.3-0.1);System.out.prin…

SEO中社交信号的重要性:Facebook分析

你可能认为 SEO中的社交信号是一些无用的社交账号&#xff0c;但它在搜索引擎优化中占有重要地位。Facebook是目前全球最大的社交媒体平台&#xff0c;它已经成为我们日常生活不可缺少的一部分。如何分析和利用好 Facebook&#xff0c;是我们学习 SEO的重中之重。在接下来的内容…

58 应用服务 hang 住, 导致服务 503 Service Unavailable

前言 这是之前 我们测试环境出现的一个问题 一个项目, 代码调整了之后, 发布到测试环境 之后, 几分钟之后 整个系统访问这个服务 出现了 "503 Service Unavailable", 然后 当时的处理方式为 临时重启服务 但是过了一会儿之后 同样的问题还是会出现, 导致 前端服务…

Functions重要部分

Functions1. Defining Functions2. Looking Up Names in Environments1. Defining Functions 赋值&#xff08;Assignment&#xff09;是一种简单的抽象方式&#xff1a;把值&#xff08;values&#xff09;和名称&#xff08;names&#xff09;联系起来。 定义函数&#xff0…

《从零开始编写一个直播服务器》 C++ 实现一个最简单的RTSP流媒体服务器

流媒体开发系列文章 文章目录流媒体开发系列文章前言一、rtsp流是什么&#xff1f;二、使用步骤1.服务器代码总结前言 在安防行业中&#xff0c;onvif协议与gb协议是两种标准&#xff0c;gb是国内安防行业的标准&#xff0c;onvif是国外的安防行业的标准&#xff0c;其中gb281…

AcWing 1013. 机器分配(分组背包问题与方案记录)

一、题目 二、思路 这道题其实不太容易看出背后的模型。这道题本质上是一个分组背包问题。我们将每一个公司看成一组&#xff0c;而在每一个组内&#xff0c;将不同情况下的盈利状况看作物品的价值&#xff0c;而得到这种利益所需的机器数目看作物品的体积。 因此&#xff0c…