文章目录

JavaScript 正则表达式:基本匹配与捕获组

发布于 2026-04-16 17:18:14 · 浏览 15 次 · 评论 0 条

JavaScript 正则表达式:基本匹配与捕获组

正则表达式是处理文本的强大工具。在JavaScript中,正则表达式可用于搜索、替换和提取文本。本文将介绍正则表达式的基本匹配规则和捕获组的用法。

基本匹配规则

创建 正则表达式有两种方式:使用字面量或构造函数。

// 字面量方式
const regex1 = /pattern/flags;

// 构造函数方式
const regex2 = new RegExp('pattern', 'flags');

1. 字符匹配

匹配 特定字符是最简单的正则表达式形式。

// 匹配字母a
const regex = /a/;
console.log(regex.test('apple')); // true
console.log(regex.test('banana')); // true
console.log(regex.test('cherry')); // false

使用 元字符可以匹配更复杂的模式。

元字符 描述 示例
. 匹配除换行外的任何字符 /a.c/ 匹配 "abc", "aac"
\d 匹配数字(0-9) /\d/ 匹配 "1", "5"
\w 匹配字母、数字和下划线 /\w/ 匹配 "a", "1", "_"
\s 匹配空白字符 /\s/ 匹配 " ", "\t", "\n"
\b 匹配单词边界 /\bcat\b/ 匹配 "cat" 但不匹配 "category"

2. 字符类

定义 字符类可以匹配一组字符中的任何一个。

// 匹配a或b
const regex = /[ab]/;
console.log(regex.test('apple')); // true
console.log(regex.test('banana')); // true
console.log(regex.test('cherry')); // false

// 匹配a-z的任何字母
const regex2 = /[a-z]/;
console.log(regex2.test('apple')); // true
console.log(regex2.test('123')); // false

使用 取反字符类匹配不在指定集中的字符。

// 匹配非数字字符
const regex = /[^0-9]/;
console.log(regex.test('a123')); // true
console.log(regex.test('123')); // false

3. 量词

指定 前面的元素可以出现多少次。

量词 描述 示例
* 匹配0次或多次 /a*/ 匹配 "", "a", "aaa"
+ 匹配1次或多次 /a+/ 匹配 "a", "aaa" 但不匹配 ""
? 匹配0次或1次 /a?/ 匹配 "", "a"
{n} 匹配恰好n次 /a{3}/ 匹配 "aaa"
{n,} 匹配至少n次 /a{2,}/ 匹配 "aa", "aaa"
{n,m} 匹配n到m次 /a{2,4}/ 匹配 "aa", "aaa", "aaaa"
// 匹配3个数字
const regex = /\d{3}/;
console.log(regex.test('123')); // true
console.log(regex.test('1234')); // true
console.log(regex.test('12')); // false

4. 锚点

指定 匹配必须出现在字符串的特定位置。

锚点 描述 示例
^ 匹配字符串开头 /^apple/ 匹配 "apple pie" 但不匹配 "pineapple"
$` | 匹配字符串结尾 | `/apple$/ 匹配 "big apple" 但不匹配 "apple pie"
\b 匹配单词边界 /\bcat\b/ 匹配 "cat" 但不匹配 "category"
// 验证邮箱格式
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
console.log(emailRegex.test('user@example.com')); // true
console.log(emailRegex.test('invalid.email')); // false
```

---

## 捕获组

**捕获组** 允许你从匹配的字符串中提取特定部分。使用括号 `()` 创建捕获组。

### 1. 基本捕获组

**创建** 基本捕获组来匹配和捕获子字符串。

```javascript
const str = '2023-10-15';
const regex = /(\d{4})-(\d{2})-(\d{2})/;
const match = str.match(regex);

console.log(match);
// 输出: ["2023-10-15", "2023", "10", "15", index: 0, input: "2023-10-15", groups: undefined]
```

**访问** 捕获组内容:

```javascript
// 完整匹配
console.log(match[0]); // "2023-10-15"

// 第一个捕获组
console.log(match[1]); // "2023"

// 第二个捕获组
console.log(match[2]); // "10"

// 第三个捕获组
console.log(match[3]); // "15"
```

### 2. 命名捕获组

**使用** `?<name>` 语法为捕获组命名,使代码更易读。

```javascript
const str = '2023-10-15';
const regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const match = str.match(regex);

console.log(match.groups.year);  // "2023"
console.log(match.groups.month); // "10"
console.log(match.groups.day);  // "15"
```

### 3. 非捕获组

**使用** `(?:)` 创建非捕获组,只匹配但不捕获内容。

```javascript
const str = 'apple, banana, cherry';
const regex = /(?:apple|banana| cherry), (pear|orange)/;
const match = str.match(regex);

console.log(match);
// 输出: ["cherry, orange", "orange", index: 14, input: "apple, banana, cherry", groups: undefined]

// 非捕获组内容不会被捕获
console.log(match[1]); // "orange" (捕获的内容)
// 非捕获组 "apple|banana| cherry" 不会出现在结果中
```

### 4. 反向引用

**引用** 前面的捕获组来匹配相同的文本。

```javascript
// 匹配重复的单词
const regex = /(\w+)\s+\1/;
console.log(regex.test('hello hello')); // true
console.log(regex.test('hello world')); // false

// 在替换中使用反向引用
const str = 'apple banana apple';
const newStr = str.replace(/(\w+)\s+(\w+)\s+(\w+)/, '$3 $2 $1');
console.log(newStr); // "apple banana apple" 变为 "apple banana apple"

实用示例

1. 表单验证

验证 电话号码格式。

// 美国电话号码格式: (123) 456-7890
const phoneRegex = /^\(\d{3}\) \d{3}-\d{4}$/;
const phoneNumber = '(123) 456-7890';
console.log(phoneRegex.test(phoneNumber)); // true
```

**验证** 密码强度(至少8个字符,包含大小写字母和数字)。

```javascript
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/;
console.log(passwordRegex.test('Weak')); // false
console.log(passwordRegex.test('StrongPass123')); // true

2. 文本处理

提取 文章中的所有URL。

const text = '访问 https://example.com 获取更多信息,或联系 mail@example.com。';
const urlRegex = /(https?:\/\/[^\s]+)/;
const urls = text.match(urlRegex);
console.log(urls[0]); // "https://example.com"

替换 文本中的特定模式。

const text = 'Hello, I am 30 years old.';
const newAge = '31';
const newText = text.replace(/I am \d+ years old/, `I am ${newAge} years old`);
console.log(newText); // "Hello, I am 31 years old."
```

### 3. 数据提取

**解析** 日志文件中的时间戳。

```javascript
const logEntry = '[2023-10-15 14:30:45] ERROR: Connection failed';
const regex = /ZGJLJSMATHTOKEN0X (\w+): (.*)/;
const match = logEntry.match(regex);
const timestamp = match[1];
const level = match[2];
const message = match[3];
console.log(`时间: ${timestamp}, 级别: ${level}, 消息: ${message}`);
// 输出: "时间: 2023-10-15 14:30:45, 级别: ERROR, 消息: Connection failed"

提取 HTML标签中的属性。

const html = '<a href="https://example.com" target="_blank">链接</a>';
const attrRegex = /<a\s+([^>]+)>/;
const match = html.match(attrRegex);
console.log(match[1]); // "href="https://example.com" target="_blank""

优化 性能的正则表达式。

// 避免使用贪婪量词导致回溯
const regex = /^a+$/; // 匹配一个或多个a
const str = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
console.log(regex.test(str)); // 高效匹配
```

### 4. 高级技巧

**使用** `RegExp` 对象的 `exec` 方法进行迭代匹配。

```javascript
const text = 'apple banana orange apple';
const regex = /\w+/;
let match;
while ((match = regex.exec(text)) !== null) {
  console.log(`找到单词: ${match[0]},位置: ${match.index}`);
}

使用 正则表达式的 sticky 标志进行连续匹配。

const text = 'abc123abc456abc';
const regex = /abc\d*/y; // y标志表示粘性匹配
regex.lastIndex = 3; // 从位置3开始
console.log(regex.exec(text)); // ["abc123", index: 3, input: "abc123abc456abc", groups: undefined]

regex.lastIndex = 9; // 从位置9开始
console.log(regex.exec(text)); // ["abc456", index: 9, input: "abc123abc456abc", groups: undefined]

正则表达式工具

使用 在线正则表达式测试工具验证和调试你的模式。

# 推荐工具
- regex101.com
- regexr.com
- regexper.com

参考 Mozilla开发者网络(MDN)获取完整的正则表达式文档。

# MDN文档
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions

学习 以下资源加深对正则表达式的理解。

# 书籍推荐
- 《精通正则表达式》(Jeffrey E.F. Friedl)
- 《正则表达式必知必会》(Ben Forta)

实践 编写正则表达式解决实际问题是最好的学习方式。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文