正则表达式[进阶]

简介: 正则表达式[进阶]

注:最后有面试挑战,看看自己掌握了吗


🌸I could be bounded in a nutshell and count myself a king of infinite space.

特别鸣谢:木芯工作室 、Ivan from Russia


限制可能的用户名

用户名在互联网上随处可见。 它们是用户在自己喜欢的网站上的唯一身份。

需要检索数据库中的所有用户名。 以下是用户在创建用户名时必须遵守的一些简单规则。

用户名只能是数字字母字符。

用户名中的数字必须在最后。 数字可以有零个或多个。 用户名不能以数字开头。

用户名字母可以是小写字母和大写字母。

用户名长度必须至少为两个字符。 两位用户名只能使用字母。

修改正则表达式 userCheck 以满足上面列出的约束。

let username = "JackOfAllTrades";
let userCheck = /^[a-z][a-z]+\d*$|^[a-z]\d\d+$/i; // 修改这一行
let result = userCheck.test(username);

匹配空白字符

迄今为止的挑战包括匹配字母和数字。 还可以匹配字符之间的空格。

可以使用 \s 搜寻空格,其中 s 是小写。 此匹配模式将匹配空格、回车符、制表符、换页符和换行符。 可以认为这类似于元字符 [ \r\t\f\n\v]

let whiteSpace = "Whitespace. Whitespace everywhere!"
let spaceRegex = /\s/g;
whiteSpace.match(spaceRegex);

这个 match 调用将返回 [" ", " "]

修改正则表达式 countWhiteSpace 查找字符串中的多个空白字符。

let sample = "Whitespace is important in separating words";
let countWhiteSpace = /\s/g; // 修改这一行
let result = sample.match(countWhiteSpace);

匹配非空白字符

已经学会了如何使用带有小写 s 的缩写 \s 来搜寻空白字符。 还可以搜寻除了空格之外的所有内容。

使用 \S 搜寻非空白字符,其中 s 是大写。 此匹配模式将不匹配空格、回车符、制表符、换页符和换行符。 可以认为这类似于元字符 [^ \r\t\f\n\v]

let whiteSpace = "Whitespace. Whitespace everywhere!"
let nonSpaceRegex = /\S/g;
whiteSpace.match(nonSpaceRegex).length;

返回值的 .length 应该是 32。

修改正则表达式 countNonWhiteSpace 以查找字符串中的多个非空字符。

指定匹配的上限和下限

回想一下,使用加号 + 查找一个或多个字符,使用星号 * 查找零个或多个字符。 这些都很方便,但有时需要匹配一定范围的匹配模式。

可以使用数量说明符(quantity specifiers)指定匹配模式的上下限。 数量说明符与花括号({ 和 })一起使用。 可以在花括号之间放两个数字,这两个数字代表匹配模式的上限和下限。

例如,要匹配出现 3 到 5 次字母 a 的在字符串 ah,正则表达式应为/a{3,5}h/。

let A4 = "aaaah";
let A2 = "aah";
let multipleA = /a{3,5}h/;
multipleA.test(A4);
multipleA.test(A2);

第一次 test 调用将返回 true,而第二次调用将返回 false。

修改正则表达式 ohRegex 以匹配出现 3 到 6 次字母 h 的字符串 Oh no。

只指定匹配的下限

可以使用带有花括号的数量说明符来指定匹配模式的上下限。 但有时候只想指定匹配模式的下限而不需要指定上限。

为此,在第一个数字后面跟一个逗号即可。

例如,要匹配至少出现 3 次字母 a 的字符串 hah,正则表达式应该是 /ha{3,}h/

let A4 = "haaaah";
let A2 = "haah";
let A100 = "h" + "a".repeat(100) + "h";
let multipleA = /ha{3,}h/;
multipleA.test(A4);
multipleA.test(A2);
multipleA.test(A100);

按顺序排列,三次 test 调用将返回值 true,false 和 true。

指定匹配的确切数量

可以使用带有花括号的数量说明符来指定匹配模式的上下限。 但有时只需要特定数量的匹配。

要指定一定数量的匹配模式,只需在大括号之间放置一个数字。

例如,要只匹配字母 a 出现 3 次的单词hah,正则表达式应为/ha{3}h/。

let A4 = "haaaah";
let A3 = "haaah";
let A100 = "h" + "a".repeat(100) + "h";
let multipleHA = /ha{3}h/;
multipleHA.test(A4);
multipleHA.test(A3);
multipleHA.test(A100);

按顺序排列,三次 test 调用将返回值 false,true 和 false。

修改正则表达式timRegex,以匹配仅有四个字母 m 的单词 Timber。

检查全部或无

有时,想要搜寻的匹配模式可能有不确定是否存在的部分。 尽管如此,还是想检查它们。

为此,可以使用问号 ? 指定可能存在的元素。 这将检查前面的零个或一个元素。 可以将此符号视为前面的元素是可选的。

例如,美式英语和英式英语略有不同,可以使用问号来匹配两种拼写。

let american = "color";
let british = "colour";
let rainbowRegex= /colou?r/;
rainbowRegex.test(american);
rainbowRegex.test(british);

上面的 test 都会返回 true。

修改正则表达式 favRegex 以匹配美式英语(favorite)和英式英语(favourite)的单词版本。

let favWord = "favorite";
let favRegex = /favou?rite/; // 修改这一行
let result = favRegex.test(favWord);

正向先行断言和负向先行断言

先行断言 (Lookaheads)是告诉 JavaScript 在字符串中向前查找的匹配模式。 当想要在同一个字符串上搜寻多个匹配模式时,这可能非常有用。

有两种先行断言:正向先行断言(positive lookahead)和负向先行断言(negative lookahead)

正向先行断言会查看并确保搜索匹配模式中的元素存在,但实际上并不匹配。 正向先行断言的用法是 (?=…),其中 … 就是需要存在但不会被匹配的部分。

另一方面,负向先行断言会查看并确保搜索匹配模式中的元素不存在。 负向先行断言的用法是 (?!..),其中 … 是希望不存在的匹配模式。 如果负向先行断言部分不存在,将返回匹配模式的其余部分。

尽管先行断言有点儿令人困惑,但是这些示例会有所帮助。

let quit = "qu";
let noquit = "qt";
let quRegex= /q(?=u)/;
let qRegex = /q(?!u)/;
quit.match(quRegex);
noquit.match(qRegex);

这两次 match 调用都将返回 ["q"]

先行断言的更实际用途是检查一个字符串中的两个或更多匹配模式。 这里有一个简单的密码检查器,密码规则是 3 到 6 个字符且至少包含一个数字:

let password = "abc123";
let checkPass = /(?=\w{3,6})(?=\D*\d)/;
checkPass.test(password);

在正则表达式 pwRegex 中使用先行断言以匹配大于 5 个字符且有两个连续数字的密码。

let sampleWord = "astronaut";
let pwRegex = /(?=\w{5,})(?=\D+\d{2,})/; // 修改这一行
let result = pwRegex.test(sampleWord);

检查混合字符组

有时候我们想使用正则表达式里的括号 () 来检查字符组。

如果想在字符串找到 Penguin 或 Pumpkin,可以用这个正则表达式:/P(engu|umpk)in/g。

然后使用 test() 方法检查 test 字符串里面是否包含字符组。

let testStr = "Pumpkin";
let testRegex = /P(engu|umpk)in/;
testRegex.test(testStr);

test 方法会返回 true。

完善正则表达式,使其以区分大小写的方式检查 Franklin Roosevelt 或 Eleanor Roosevelt 的名字,并且应该忽略 middle names。

然后完善代码,使创建的正则检查 myString,根据正则是否匹配返回 true 或 false

let myString = "Eleanor Roosevelt";
let myRegex = /(Franklin|Eleanor) (([A-Z]\.?|[A-Z][a-z]+) )?Roosevelt/;
let result = myRegex.test(myString);

使用捕获组重用模式

当你想要匹配一个像下面这样多次出现的单词,

let repeatStr = "row row row your boat";

你可以使用 /row row row/。但如果你不知道重复的特定单词,怎么办? 捕获组 可以用于找到重复的子字符串。

捕获组是通过把要捕获的正则表达式放在括号中来构建的。 在这个例子里, 目标是捕获一个包含字母数字字符的词,所以捕获组是将 \w+ 放在括号中/(\w+)/。

分组匹配的子字符串被保存到一个临时的“变量”, 可以使用同一正则表达式和反斜线及捕获组的编号来访问它(例如:\1)。 捕获组按其开头括号的位置自动编号(从左到右),从 1 开始

下面的示例是匹配被空格隔开的两个相同单词:

let repeatRegex = /(\w+) \1 \1/;
repeatRegex.test(repeatStr); // Returns true
repeatStr.match(repeatRegex); // Returns ["row row row", "row"]

在字符串上调用 .match() 方法将返回一个数组,其中包含它最终匹配到的子字符串及其捕获组。

在 reRegex 中使用捕获组来匹配一个只由相同的数字重复三次组成的由空格分隔字符串。

let repeatNum = "42 42 42";
let reRegex = /^(\d+) \1 \1$/g; // 修改这一行
let result = reRegex.test(repeatNum);

使用捕获组搜索和替换

搜索功能是很有用的。 但是,当搜索同时也执行更改(或替换)匹配文本的操作时,搜索功能就会显得更加强大。

可以在字符串上使用 .replace() 方法来搜索并替换字符串中的文本。 .replace() 的输入首先是想要搜索的正则表达式匹配模式。 第二个参数是用于替换匹配的字符串或用于执行某些操作的函数

let wrongText = "The sky is silver.";
let silverRegex = /silver/;
wrongText.replace(silverRegex, "blue");

replace 调用将返回字符串 The sky is blue.。

你还可以使用美元符号($)访问替换字符串中的捕获组

"Code Camp".replace(/(\w+)\s(\w+)/, '$2 $1');

调用 replace 将返回字符串 Camp Code

使用三个捕获组编写一个正则表达式 fixRegex,这三个捕获组将搜索字符串 one two three 中的每个单词。 然后更新 replaceText 变量,以字符串 three two one 替换 one two three,并将结果分配给 result 变量。 确保使用美元符号($)语法在替换字符串中使用捕获组。

let str = "one two three";
let fixRegex = /^(\w+)\s(\w+)\s(\w+)$/g; // 修改这一行
let replaceText = "$3 $2 $1"; // 修改这一行
let result = str.replace(fixRegex, replaceText);

删除开头和结尾的空白

有时字符串周围存在的空白字符并不是必需的。 字符串的典型处理是删除字符串开头和结尾处的空格。

编写一个正则表达式并使用适当的字符串方法删除字符串开头和结尾的空格。

注意: String.prototype.trim() 方法在这里也可以实现同样的效果,但是你需要使用正则表达式来完成此项挑战。

let hello = "   Hello, World!  ";
let wsRegex = /^(\s+)|(\s+)$/g; // 修改这一行
let result = hello.replace(wsRegex,""); // 修改这一行
相关文章
|
Java Linux Apache
Maven下载和配置教程:Windows、Mac和Linux系统安装指南
Maven下载和配置教程:Windows、Mac和Linux系统安装指南
1449 0
|
10月前
|
人工智能 搜索推荐 数据挖掘
企业客户管理升级:销售易、白码、纷享销客CRM的功能与适用企业洞察
销售易CRM、白码CRM和纷享销客CRM各有特色。销售易CRM以移动化、社交化和AI技术为核心,适合大型企业及跨国公司,助力销售流程数字化转型。白码CRM是低代码开发平台,支持快速构建企业应用,适合中小型企业,降低数字化门槛。纷享销客CRM强调社交化客户关系管理和项目协作,适用于服务导向型企业和注重团队协作的企业。选择时应根据自身需求和规模,挑选最适合的解决方案。
|
8月前
|
消息中间件 分布式计算 并行计算
Python 高级编程与实战:构建分布式系统
本文深入探讨了 Python 中的分布式系统,介绍了 ZeroMQ、Celery 和 Dask 等工具的使用方法,并通过实战项目帮助读者掌握这些技术。ZeroMQ 是高性能异步消息库,支持多种通信模式;Celery 是分布式任务队列,支持异步任务执行;Dask 是并行计算库,适用于大规模数据处理。文章结合具体代码示例,帮助读者理解如何使用这些工具构建分布式系统。
|
9月前
|
监控 关系型数据库 MySQL
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
【01】客户端服务端C语言-go语言-web端PHP语言整合内容发布-优雅草网络设备监控系统-硬件设备实时监控系统运营版发布-本产品基于企业级开源项目Zabbix深度二开-分步骤实现预计10篇合集-自营版
280 0
|
监控 中间件 UED
中间件数据传输数据一致性
中间件在跨系统数据传输中确保一致性至关重要,采用事务处理、数据校验和验证、分布式一致性协议(如Raft、Paxos)、数据复制与同步、错误处理及重试机制、监控日志记录和选择合适的一致性级别(如强一致或最终一致)等策略,能有效提高传输的可靠性和数据一致性。
254 2
|
机器学习/深度学习 人工智能 安全
人工智能与机器学习在网络安全中的应用
人工智能与机器学习在网络安全中的应用
360 0
|
机器学习/深度学习 自然语言处理 并行计算
【YOLOv8改进 -注意力机制】Mamba之MLLAttention :基于Mamba和线性注意力Transformer的模型
YOLOv8专栏探讨了该目标检测模型的创新改进,包括使用Mamba模型的线性注意力Transformer变体,称为MLLA。Mamba的成功关键在于遗忘门和块设计,MLLA结合了这些优点,提升了视觉任务的性能。文章提供全面分析,并提出MLLA模型,其在效率和准确性上超过多种视觉模型。论文和代码可在提供的链接中找到。MLLA Block的代码示例展示了如何整合关键组件以实现高效运算。更多配置详情见相关链接。
|
JavaScript 程序员 网络架构
vue路由从入门到进阶 --- 声明式导航详细教程
vue路由从入门到进阶 --- 声明式导航详细教程
vue路由从入门到进阶 --- 声明式导航详细教程
|
存储 缓存 固态存储
三分钟解决AE缓存预览渲染错误、暂停、卡顿问题
三分钟解决AE缓存预览渲染错误、暂停、卡顿问题
3074 2