一、是什么

正则表达式是一种用来匹配字符串的强有力的武器

它的设计思想是用一种描述性的语言定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的

在 JavaScript中,正则表达式也是对象,构建正则表达式有两种方式:

  1. 字面量创建,其由包含在斜杠之间的模式组成
    const re = /\d+/g;
    
  2. 调用RegExp对象的构造函数
const re = new RegExp("\\d+","g");const rul = "\\d+"
const re1 = new RegExp(rul,"g");

使用构建函数创建,第一个参数可以是一个变量,遇到特殊字符\需要使用\\进行转义

二、匹配规则

常见的校验规则如下:

规则描述
\转义
^匹配输入的开始
$匹配输入的结束
*匹配前一个表达式 0 次或多次
+匹配前面一个表达式 1 次或者多次。等价于 {1,}
?匹配前面一个表达式 0 次或者 1 次。等价于{0,1}
.默认匹配除换行符之外的任何单个字符
x(?=y)匹配'x'仅仅当'x'后面跟着'y'。这种叫做先行断言
(?<=y)x匹配'x'仅当'x'前面是'y'.这种叫做后行断言
x(?!y)仅仅当'x'后面不跟着'y'时匹配'x',这被称为正向否定查找
(?<!y)x仅仅当'x'前面不是'y'时匹配'x',这被称为反向否定查找
x|y匹配‘x’或者‘y’
{n}n 是一个正整数,匹配了前面一个字符刚好出现了 n 次
{n,}n是一个正整数,匹配前一个字符至少出现了n次
{n,m}n 和 m 都是整数。匹配前面的字符至少n次,最多m次
[xyz]一个字符集合。匹配方括号中的任意字符
[^xyz]匹配任何没有包含在方括号中的字符
\b匹配一个词的边界,例如在字母和空格之间
\B匹配一个非单词边界
\d匹配一个数字
\D匹配一个非数字字符
\f匹配一个换页符
\n匹配一个换行符
\r匹配一个回车符
\s匹配一个空白字符,包括空格、制表符、换页符和换行符
\S匹配一个非空白字符
\w匹配一个单字字符(字母、数字或者下划线)
\W匹配一个非单字字符

正则表达式标记

标志描述
g全局搜索。
i不区分大小写搜索。
m多行搜索。
s允许 . 匹配换行符。
u使用unicode码的模式进行匹配。
y执行“粘性(sticky)”搜索,匹配从目标字符串的当前位置开始。

使用方法如下:

var re = /pattern/flags;
var re = new RegExp("pattern", "flags");

在了解下正则表达式基本的之外,还可以掌握几个正则表达式的特性:

贪婪模式

在了解贪婪模式前,首先举个例子:

const reg = /ab{1,3}c/

在匹配过程中,尝试可能的顺序是从多往少的方向去尝试。首先会尝试bbb,然后再看整个正则是否能匹配。不能匹配时,吐出一个b,即在bb的基础上,再继续尝试,以此重复

如果多个贪婪量词挨着,则深度优先搜索

const string = "12345";
const regx = /(\d{1,3})(\d{1,3})/;
console.log( string.match(reg) );
// => ["12345", "123", "45", index: 0, input: "12345"]

其中,前面的\d{1,3}匹配的是"123",后面的\d{1,3}匹配的是"45"

懒惰模式

惰性量词就是在贪婪量词后面加个问号。表示尽可能少的匹配

其中\d{1,3}?只匹配到一个字符"1",而后面的\d{1,3}匹配了"234"

分组

分组主要是用过()进行实现,比如beyond{3},是匹配d字母3次。而(beyond){3}是匹配beyond三次

()内使用|达到或的效果,如(abc | xxx)可以匹配abc或者xxx

反向引用,巧用$分组捕获

let str = "John Smith";// 交换名字和姓氏
console.log(str.replace(/(john) (smith)/i, '$2, $1')) // Smith, John

三、匹配方法

正则表达式常被用于某些方法,我们可以分成两类:

  • 字符串(str)方法:matchmatchAllsearchreplacesplit
  • 正则对象下(regexp)的方法:testexec
方法描述
exec一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回 null)。
test一个在字符串中测试是否匹配的RegExp方法,它返回 true 或 false。
match一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null。
matchAll一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator)。
search一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。
replace一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。
split一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String 方法。

str.match(regexp)

str.match(regexp) 方法在字符串 str 中找到匹配 regexp 的字符

如果 regexp 不带有 g 标记,则它以数组的形式返回第一个匹配项,其中包含分组和属性 index(匹配项的位置)、input(输入字符串,等于 str

let str = "I love JavaScript";let result = str.match(/Java(Script)/);console.log( result[0] );     // JavaScript(完全匹配)
console.log( result[1] );     // Script(第一个分组)
console.log( result.length ); // 2// 其他信息:
console.log( result.index );  // 7(匹配位置)
console.log( result.input );  // I love JavaScript(源字符串)

如果 regexp 带有 g 标记,则它将所有匹配项的数组作为字符串返回,而不包含分组和其他详细信息

let str = "I love JavaScript";let result = str.match(/Java(Script)/g);console.log( result[0] ); // JavaScript
console.log( result.length ); // 1

如果没有匹配项,则无论是否带有标记 g ,都将返回 null

let str = "I love JavaScript";let result = str.match(/HTML/);console.log(result); // null

str.matchAll(regexp)

返回一个包含所有匹配正则表达式的结果及分组捕获组的迭代器

const regexp = /t(e)(st(\d?))/g;
const str = 'test1test2';const array = [...str.matchAll(regexp)];console.log(array[0]);
// expected output: Array ["test1", "e", "st1", "1"]console.log(array[1]);
// expected output: Array ["test2", "e", "st2", "2"]

str.search(regexp)

返回第一个匹配项的位置,如果未找到,则返回 -1

let str = "A drop of ink may make a million think";console.log( str.search( /ink/i ) ); // 10(第一个匹配位置)

这里需要注意的是,search 仅查找第一个匹配项

str.replace(regexp)

替换与正则表达式匹配的子串,并返回替换后的字符串。在不设置全局匹配g的时候,只替换第一个匹配成功的字符串片段

const reg1=/javascript/i;
const reg2=/javascript/ig;
console.log('hello Javascript Javascript Javascript'.replace(reg1,'js'));
//hello js Javascript Javascript
console.log('hello Javascript Javascript Javascript'.replace(reg2,'js'));
//hello js js js

str.split(regexp)

使用正则表达式(或子字符串)作为分隔符来分割字符串

console.log('12, 34, 56'.split(/,\s*/)) // 数组 ['12', '34', '56']

regexp.exec(str)

regexp.exec(str) 方法返回字符串 str 中的 regexp 匹配项,与以前的方法不同,它是在正则表达式而不是字符串上调用的

根据正则表达式是否带有标志 g,它的行为有所不同

如果没有 g,那么 regexp.exec(str) 返回的第一个匹配与 str.match(regexp) 完全相同

如果有标记 g,调用 regexp.exec(str) 会返回第一个匹配项,并将紧随其后的位置保存在属性regexp.lastIndex 中。 下一次同样的调用会从位置 regexp.lastIndex 开始搜索,返回下一个匹配项,并将其后的位置保存在 regexp.lastIndex 中

let str = 'More about JavaScript at https://javascript.info';
let regexp = /javascript/ig;let result;while (result = regexp.exec(str)) {console.log( `Found ${result[0]} at position ${result.index}` );// Found JavaScript at position 11// Found javascript at position 33
}

regexp.test(str)

查找匹配项,然后返回 true/false 表示是否存在

let str = "I love JavaScript";// 这两个测试相同
console.log( /love/i.test(str) ); // true

四、应用场景

通过上面的学习,我们对正则表达式有了一定的了解

下面再来看看正则表达式一些案例场景:

验证QQ合法性(5~15位、全是数字、不以0开头):

const reg = /^[1-9][0-9]{4,14}$/
const isvalid = patrn.exec(s)

校验用户账号合法性(只能输入5-20个以字母开头、可带数字、“_”、“.”的字串):

var patrn=/^[a-zA-Z]{1}([a-zA-Z0-9]|[._]){4,19}$/;
const isvalid = patrn.exec(s)

url参数解析为对象

const protocol = '(?<protocol>https?:)';
const host = '(?<host>(?<hostname>[^/#?:]+)(?::(?<port>\\d+))?)';
const path = '(?<pathname>(?:\\/[^/#?]+)*\\/?)';
const search = '(?<search>(?:\\?[^#]*)?)';
const hash = '(?<hash>(?:#.*)?)';
const reg = new RegExp(`^${protocol}\/\/${host}${path}${search}${hash}$`);
function execURL(url){const result = reg.exec(url);if(result){result.groups.port = result.groups.port || '';return result.groups;}return {protocol:'',host:'',hostname:'',port:'',pathname:'',search:'',hash:'',};
}console.log(execURL('https://localhost:8080/?a=b#xxxx'));
protocol: "https:"
host: "localhost:8080"
hostname: "localhost"
port: "8080"
pathname: "/"
search: "?a=b"
hash: "#xxxx"

再将上面的searchhash进行解析

function execUrlParams(str){str = str.replace(/^[#?&]/,'');const result = {};if(!str){ //如果正则可能配到空字符串,极有可能造成死循环,判断很重要return result; }const reg = /(?:^|&)([^&=]*)=?([^&]*?)(?=&|$)/ylet exec = reg.exec(str);while(exec){result[exec[1]] = exec[2];exec = reg.exec(str);}return result;
}
console.log(execUrlParams('#'));// {}
console.log(execUrlParams('##'));//{'#':''}
console.log(execUrlParams('?q=3606&src=srp')); //{q: "3606", src: "srp"}
console.log(execUrlParams('test=a=b=c&&==&a='));//{test: "a=b=c", "": "=", a: ""}

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java锁机制知识点

一、锁的基础概念 1.1 什么是锁 在并发编程中&#xff0c;锁是用于控制多个线程对共享资源进行访问的机制。锁可以保证在同一时刻最多只有一个线程访问共享资源&#xff0c;从而保证数据的一致性。 1.2 锁的分类 可重入锁 vs 不可重入锁&#xff1a;可重入锁允许同一个线程…

2025下半年软考软件设计师(中级)怎么高效备考,目标是稳过线!

25下半年软考开始进入备考阶段&#xff0c;现在咱们就抛开那些文绉绉的官话&#xff0c;用大白话来聊聊2025下半年软考软件设计师&#xff08;中级&#xff09;怎么高效备考&#xff0c;目标是稳过线&#xff01; 核心思想&#xff1a;抓大放小&#xff0c;真题为王&#xff0…

Jupyter常见操作(持续更新)

Jupyter常见操作&#xff08;持续更新&#xff09; 本文主要整理一些常见的或者比较简单的Jupyter操作&#xff0c;尽量保证一次性整理出来&#xff0c;方便需要但是忘记的情况下可以直接查&#xff0c;希望能当字典。 1.查看Jupyter内核 jupyter kernelspec list 2.使用指定…

连点成画面积计算算法

连点成画面积计算算法 问题分析与算法设计 1. 问题特征分析 闭合多边形(起点和终点相同)线段可能交叉形成复杂形状需要处理自交多边形可能有多个内部空洞点数较多(≥50个点),需要高效算法2. 解决方案选择 采用平面扫描算法结合多边形布尔运算来准确计算最外层边界包围的…

华为云Flexus+DeepSeek征文 | 华为云MaaS平台上的智能客服Agent开发:多渠道融合应用案例

华为云FlexusDeepSeek征文 | 华为云MaaS平台上的智能客服Agent开发&#xff1a;多渠道融合应用案例 &#x1f31f; 嗨&#xff0c;我是IRpickstars&#xff01; &#x1f30c; 总有一行代码&#xff0c;能点亮万千星辰。 &#x1f50d; 在技术的宇宙中&#xff0c;我愿做永不…

03.BUG

Bug 1.软件测试的生命周期2. BUG2.1 表述BUG的要素2.2 BUG级别2.3 BUG的声命周期 1.软件测试的生命周期 ​ 软件测试贯穿于软件的整个生命周期&#xff1a;软件测试的生命周期&#xff08;Software Testing Life Cycle, STLC&#xff09;,是指测试流程&#xff0c;这个流程是按…

【数据标注师】问答标注

目录 一、 **问答标注的认知底层架构**1. **三维评估体系**2. **四类问题处理范式** 二、 **五阶能力培养体系**▶ **阶段1&#xff1a;问题解析能力筑基&#xff08;2周&#xff09;**▶ **阶段2&#xff1a;答案质量评估训练**▶ **阶段3&#xff1a;复杂场景处理**▶ **阶段…

使用DBeaver 连接mysql,使用存储过程插入5万条数据

使用DBeaver连接MySQL并创建存储过程生成5万条数据 连接MySQL数据库 打开DBeaver&#xff0c;点击"数据库"菜单选择"新建连接"&#xff0c;选择MySQL驱动。填写主机、端口、数据库名称、用户名和密码等信息&#xff0c;测试连接成功后保存。 创建测试表…

某省赛题-windows内存取证

1.获取admin用户密码是多少&#xff1f; 这里我们使用hashdump之后用john爆破没有结果&#xff0c;然后使用lsadump出来了flag 2.获取ip和主机名是什么&#xff1f; 主机名&#xff1a; 看注册表 SAM&#xff1a;记录了所有的用户 SYSTEM&#xff1a;可以看主机名 SOFTWARE&a…

【软考高项论文】论信息系统项目的成本管理

摘要 在信息系统项目管理里&#xff0c;成本管理是极为关键的环节&#xff0c;直接影响项目的顺利开展与最终成败。本文结合项目管理实际情况&#xff0c;从项目成本基准的形成过程、项目S曲线的绘制以及成本控制的具体实施三个方面&#xff0c;详细阐述了对信息系统项目成本管…

AI人工智能技术应用于人社服务领域的创新研究报告

AI 人工智能技术应用于人社服务领域的创新研究报告 一、研究背景与市场概况 1.1 研究背景与政策环境 人工智能技术正深刻改变政府治理模式和公共服务方式。在国家全面推进数字化转型的战略背景下,人社部《数字人社建设行动实施方案》明确提出:到 2025 年,人社数字化底座…

javaEE-mybatis操作数据库

前言 在MySQL的学习阶段&#xff0c;我们知道了如何使用JDBC去操作&#xff0c;也正是因为学习了JDBC也知道其操作的繁琐&#xff0c;每次的CRUD操作都需要从数据库连接池中去获取数据库连接&#xff0c;然后再编写SQL语句&#xff0c;并绑定对应的参数&#xff0c;接着通过连…

移动端测试——如何解决iOS端无法打开弹窗式网页(Webkit)

目录 一、什么是webkit&#xff1f; 1. 核心定义 2. iOS 的特殊限制 3. 弹窗拦截的逻辑 二、为什么 iOS 必须用 WebKit&#xff1f; 1. 苹果的官方理由 2. 实际后果 3.然而…… 三、如何解决iOS端无法打开弹窗式网页&#xff1f; 1.用户 1.1 safari浏览器 1.2 夸克…

【github】从本地更新仓库里的文件笔记

1. 打开GitHub官网&#xff0c;并登录到您的账户。 2. 在页面右上角的搜索栏中&#xff0c;输入您要更新的仓库名称&#xff0c;并选择相应的仓库进入。 3. 在仓库页面中&#xff0c;找到并点击红色的“Code”按钮&#xff0c;然后复制仓库的HTTPS或者SSH链接。 4. 右键包含…

Excel基础:数据编辑

Excel是Windows下最常用的数据处理工具&#xff0c;本文详细介绍Excel的数据编辑功能&#xff0c;熟练掌握编辑技巧能可以极大提升工作效率&#xff0c;文章最后附加了一张总结思维导图&#xff0c;方便大家查找和记忆。 文章目录 一、数据输入1.1 覆盖输入1.2 追加输入1.3 任…

JavaScript中Object()的解析与应用

在JavaScript中&#xff0c;Object() 是一个基础构造函数&#xff0c;用于创建对象或转换值为对象类型。它既是语言的核心组成部分&#xff0c;也提供了一系列静态方法用于对象操作。以下是详细解析和应用示例&#xff1a; 一、Object() 的基本行为 作为构造函数&#xff08;…

stream使用案例

1.1 查找所有的偶数并求和 public static void p1() { List<Integer> numbers Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); int sum numbers.stream() .filter(num -> num % 2 0) .mapToInt(Integer::intValue) .sum() ; System.err.printf…

力扣 刷题(第七十一天)

灵感来源 - 保持更新&#xff0c;努力学习 - python脚本学习 4的幂 解题思路 位运算条件&#xff1a;4 的幂的二进制表示中只有一个 1&#xff0c;且位于奇数位&#xff08;如 4 100&#xff0c;4 10000&#xff09;。模运算条件&#xff1a;4 的幂减 1 后能被 3 整除&…

深度学习使用Pytorch训练模型步骤

训练模型是机器学习和深度学习中的核心过程&#xff0c;旨在通过大量数据学习模型参数&#xff0c;以便模型能够对新的、未见过的数据做出准确的预测。 训练模型通常包括以下几个步骤&#xff1a; 1.数据准备&#xff1a; 收集和处理数据&#xff0c;包括清洗、标准化和归一化…

Unity_导航操作(鼠标控制人物移动)_运动动画

文章目录 前言一、Navigation 智能导航地图烘焙1.创建Plan和NavMesh Surface2.智能导航地图烘焙 二、MouseManager 鼠标控制人物移动1.给场景添加人物&#xff0c;并给人物添加导航组件2.编写脚本管理鼠标控制3.给人物编写脚本&#xff0c;订阅事件&#xff08;添加方法给Mouse…