详解正则表达式中的?:、?= 、 ?! 、?<=、?<!

1、?: - 非捕获组

语法: (?:pattern)

作用: 创建一个分组但不捕获匹配结果,不会将匹配的文本存储到内存中供后续使用。

优势:

  • 提高性能和效率
  • 不占用编号(不会影响后续捕获组的编号)
  • 减少内存使用
javascript 复制代码
// 使用捕获组
let regex1 = /(hello|hi) world/;
let match1 = "hello world".match(regex1);
console.log(match1);  // ["hello world", "hello"]

// 使用非捕获组
let regex2 = /(?:hello|hi) world/;
let match2 = "hello world".match(regex2);
console.log(match2);  // ["hello world"]

在以上例子中,除了完整匹配外,还捕获了"hello"。而在第二个例子中,只返回了完整匹配,不会捕获括号内的内容。

2、?= - 正向先行断言

语法: (?=pattern)

作用: 匹配后面跟着特定模式的位置,但不消耗这些字符(零宽度断言)。

特点:

  • 只断言位置,不匹配实际字符
  • 不会将断言的内容包含在最终匹配结果中
javascript 复制代码
// 匹配后面是"元"的数字
let regex = /\d+(?=元)/;
let text = "价格是100元";
let match = text.match(regex);
console.log(match);  // ["100"]

// 匹配后面是闭标签的所有内容
let html = "<div>内容</div>";
let content = html.match(/.+(?=<\/div>)/);
console.log(content);  // ["<div>内容"]

在这个例子中,正向先行断言确保了特定内容存在于匹配之后,但不包含在匹配结果中。

3、?! - 负向先行断言

语法: (?!pattern)

作用: 匹配后面不跟着特定模式的位置。

特点:

  • 零宽度断言,只匹配位置
  • 用于排除某些模式
javascript 复制代码
// 匹配不以数字结尾的单词
let regex = /\b\w+(?!\d)\b/g;
let text = "apple1 banana orange2";
let matches = text.match(regex);
console.log(matches);  // ["banana"]

// 匹配不后接元的数字
let priceText = "100元 200美元 300";
let numbers = priceText.match(/\d+(?!元)/g);
console.log(numbers);  // ["200", "300"]

第一个例子匹配不以数字结尾的单词,第二个例子匹配后面不跟"元"的数字。

4、?<= - 正向后行断言

语法: (?<=pattern)

作用: 匹配前面有特定模式的位置。

特点:

  • 零宽度断言,查看匹配位置之前的内容
  • 不消耗字符,不包含在匹配结果中
javascript 复制代码
// 匹配前面是货币符号的数字
let regex = /(?<=[$¥€£])(\d+(\.\d+)?)/g;
let text = "$100 ¥200 €300";
let matches = text.match(regex);
console.log(matches);  // ["100", "200", "300"]

// 匹配标签内的内容
let html = "<div>内容</div>";
let content = html.match(/(?<=<div>).*(?=<\/div>)/);
console.log(content);  // ["内容"]

第一个例子匹配前面有货币符号的数字,第二个例子匹配div标签内的内容。

5、?<! - 负向后行断言

语法: (?<!pattern)

作用: 匹配前面没有特定模式的位置。

特点:

  • 零宽度断言,排除特定前缀
  • 不消耗字符,只断言位置
javascript 复制代码
// 匹配不在discount-后面的数字
let regex = /(?<!discount-)\d+/g;
let text = "price-100 discount-50 item-200";
let matches = text.match(regex);
console.log(matches);  // ["100", "200"]

// 匹配不以https://开头的URL
let urlRegex = /(?<!https:\/\/)www\.\w+\.\w+/g;
let urls = "http://www.example.com https://www.secure.com";
let httpUrls = urls.match(urlRegex);
console.log(httpUrls);  // ["www.example.com"]

第一个例子匹配不在"discount-"后面的数字,第二个例子匹配不以"https://"开头的URL。

相关推荐
女王大人万岁几秒前
Go语言JSON标准库(encoding/json):功能解析与实战指南
服务器·开发语言·后端·golang·json
恋猫de小郭1 分钟前
小米 HyperOS 4 大变样?核心应用以 Rust / Flutter 重写,不兼容老系统
android·前端·人工智能·flutter·ios
摘星编程2 分钟前
OpenHarmony环境下React Native:Loading全屏加载遮罩
javascript·react native·react.js
wjs20243 分钟前
Scala 基础语法
开发语言
.ZGR.4 分钟前
从游戏到实战的线程进阶之旅:智能无人机防空平台
java·开发语言·无人机
上海合宙LuatOS4 分钟前
LuatOS ——fota 升级教程
开发语言·人工智能·单片机·嵌入式硬件·物联网·php·硬件工程
NWU_白杨5 分钟前
智能无人机平台V4
java·开发语言·无人机
小高Baby@6 分钟前
Go语言中面向对象的三大特性之继承的理解
开发语言·后端·golang
小高Baby@6 分钟前
Go语言中面向对象的三大特性之封装的理解
开发语言·后端·golang
李火火的安全圈7 分钟前
基于Yakit、Wavely实现CVE-2025-55182(React Server Components(RSC)) 反序列化漏洞挖掘和POC编写
前端·react.js