1
0
wiki/Technology/GettingStarted/文本处理/正则表达式.md
2024-08-30 12:29:55 +08:00

180 lines
9.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: 正则表达式
description: 正则表达式基础入门
keywords:
- 正则表达式
tags:
- 技术/入门
author: 仲平
date: 2024-05-13
---
## 概述
正则表达式Regular ExpressionRegex是用于匹配字符串中字符组合的模式。它由一系列字符和特殊符号组成可以高效地执行查找、替换、检查数据格式等多种文本处理任务。正则表达式的概念最初由数学家斯蒂芬·克莱尼在 20 世纪 50 年代提出,最早用于理论计算机科学和形式语言理论中。
几乎所有现代编程语言都支持正则表达式,包括 Python、JavaScript、Java、C#等。此外,许多文本编辑器和开发环境(如 VSCode、Sublime Text以及命令行工具如 grep也广泛应用正则表达式进行文本搜索和编辑。
## 基本概念
- **字面字符**:指在表达式中表示它们自身字面意义的字符,例如 `a`、`1`、`B`。
- **特殊字符**:在正则表达式中用来表示控制或通配符作用的字符,如 `*`(匹配前一个字符 0 次或多次)。
### 元字符
元字符是构成正则表达式逻辑的基础,具有特殊的匹配含义:
| 元字符 | 描述 |
| ------- | ------------------------------------------------------------ |
| `.` | 句号匹配任意单个字符除了换行符。 |
| `[ ]` | 字符种类。匹配方括号内的任意字符。 |
| `[^ ]` | 否定的字符种类。匹配除了方括号里的任意字符 |
| `*` | 匹配 >=0 个重复的在 * 号之前的字符。 |
| `+` | 匹配 >=1 个重复的 + 号前的字符。 |
| `?` | 标记 ? 之前的字符为可选。 |
| `{n,m}` | 匹配 num 个大括号之前的字符或字符集 (n <= num <= m)。 |
| `(xyz)` | 字符集,匹配与 xyz 完全相等的字符串。 |
| `|` | 或运算符,匹配符号前或后的字符。 |
| `\` | 转义字符,用于匹配一些保留的字符 `[ ] ( ) { } . * + ? ^ $ \ |`。 |
| `^` | 从开始行开始匹配。 |
| `$` | 从末端开始匹配。 |
### 字符类
字符类允许匹配指定集合中的字符,常见的标准字符类和自定义字符类如下:
| 简写 | 描述 |
| ---- | -------------------------------------------------- |
| `.` | 除换行符外的所有字符 |
| `\w` | 匹配所有字母数字,等同于 `[a-zA-Z0-9_]` |
| `\W` | 匹配所有非字母数字,即符号,等同于: `[^\w]` |
| `\d` | 匹配数字: `[0-9]` |
| `\D` | 匹配非数字: `[^\d]` |
| `\s` | 匹配所有空格字符,等同于: `[\t\n\f\r\p{Z}]` |
| `\S` | 匹配所有非空格字符: `[^\s]` |
| `\f` | 匹配一个换页符 |
| `\n` | 匹配一个换行符 |
| `\r` | 匹配一个回车符 |
| `\t` | 匹配一个制表符 |
| `\v` | 匹配一个垂直制表符 |
| `\p` | 匹配 CR/LF等同于 `\r\n`),用来匹配 DOS 行终止符 |
**自定义字符类**
| 示例 | 描述 |
| --------- | ----------------------------------------------- |
| `[a-z]` | 匹配任何小写字母 |
| `[A-Z]` | 匹配任何大写字母 |
| `[0-9]` | 匹配任何数字 |
| `[aeiou]` | 匹配所有小写元音字母 |
| `[^0-9]` | 匹配任何不是数字的字符(方括号内的 `^` 表示非) |
### 位置匹配
位置匹配用于确定字符匹配的具体位置,如行首或行尾等:
| 锚点字符 | 描述 |
| -------- | ------------------------------------------------------------ |
| `^` | 不仅表示行的开始,也可在多行模式中匹配每一行的开始 |
| `$` | 表示行的结束或字符串的结束,同样在多行模式中可匹配每一行的结束 |
## 量词和分组
量词和分组是正则表达式中非常强大的功能,它们让我们可以定义复杂的模式,进行精确的文本匹配和操作。这部分内容也可以用表格形式进行更清晰的展示。
### 量词
量词用于指定一个元素出现的次数,是正则表达式中控制匹配频度的关键工具。
| 量词 | 描述 |
| ------- | ------------------------------------ |
| `*` | 匹配前一个元素 0 次或多次。 |
| `+` | 匹配前一个元素 1 次或多次。 |
| `?` | 匹配前一个元素 0 次或 1 次。 |
| `{n}` | 匹配前一个元素恰好 n 次。 |
| `{n,}` | 匹配前一个元素至少 n 次。 |
| `{n,m}` | 匹配前一个元素至少 n 次,但不超过 m 次。 |
#### 贪婪与非贪婪量词
量词默认为贪婪模式,尽可能多地匹配字符。通过添加 `?` 后缀,量词变为非贪婪模式,尽可能少地匹配字符。
| 类型 | 示例 | 描述 |
| ---------- | ------- | ------------------------------------------------------- |
| 贪婪匹配 | `a.*b` | 在 `axxxbxxxb` 中匹配从第一个 `a` 到最后一个 `b` 的整段文本。 |
| 非贪婪匹配 | `a.*?b` | 在 `axxxbxxxb` 中匹配最短的,以 `a` 开始,以 `b` 结束的文本。 |
### 分组和引用
分组允许将正则表达式中的部分模式括起来,作为一个整体进行操作,这对于提取信息、构建复杂模式或进行条件匹配非常有用。
#### 捕获分组与非捕获分组
| 类型 | 示例 | 描述 |
| ---------- | --------- | ----------------------------------------------- |
| 捕获分组 | `(abc)` | 匹配 `abc`,并捕获匹配的文本,以供后续引用。 |
| 非捕获分组 | `(?:abc)` | 匹配 `abc`,但不捕获匹配的文本,仅用于匹配操作。 |
#### 后向引用
后向引用让我们能够引用正则表达式中先前定义的捕获组,这对于匹配重复的文本或验证两部分内容相同非常有用。
| 示例 | 描述 |
| -------------- | --------------------------------------------------------- |
| `(\b\w+)\s+\1` | 匹配一个由单词、空格和相同单词构成的模式,如 `word word`。 |
## 高级匹配
### 断言
断言是正则表达式中的一个高级特性,允许进行条件匹配,即只有在满足特定条件的情况下才进行匹配。
| 符号 | 描述 |
| ---- | --------------- |
| `?=` | 正先行断言 - 存在 |
| `?!` | 负先行断言 - 排除 |
| `?<=` | 正后发断言 - 存在 |
| `?<!` | 负后发断言 - 排除 |
**前向肯定断言** (`?=`)
- 前向肯定断言允许你指定一个子模式必须出现在某个匹配之后,但不会成为匹配结果的一部分。例如,`a(?=b)` 会匹配前面有 `a` 且后面紧跟 `b` 的位置,但不会返回 `b`
**前向否定断言** (`?!`)
- 前向否定断言用来指定一个子模式必须不出现在某个匹配之后。例如,`a(?!b)` 会匹配所有后面不跟 `b``a`
**后向断言**
- 在支持的语言中(如 JavaScript后向断言允许你指定一个子模式必须出现在某个匹配之前。如 `(?<=b)a` 表示 `a` 前面必须有 `b`
### 标志/模式修饰符
标志或模式修饰符用于改变正则表达式的匹配行为。
| 标志 | 描述 |
| ---- | ----------------------------------------------------- |
| `i` | 忽略大小写。 |
| `g` | 全局搜索。 |
| `m` | 多行修饰符:锚点元字符 `^` `$` 工作范围在每行的起始。 |
**大小写不敏感** (`i`)
- 使用此标志后,匹配时将不区分大小写。例如,正则表达式 `/abc/i` 将匹配 `Abc`、`aBc`、`abc` 等。
**多行模式** (`m`)
- 在多行模式下,`^` 和 `$` 不仅匹配输入字符串的开始和结束位置,也匹配行的开始和结束。
**点号包含换行** (`s`)
- 通常,`.` 不匹配换行符。使用此标志后,`.` 也将匹配换行符。
## 参考实例
- [regex101正则表达式测试工具](https://regex101.com/)
- [REGEXP正则表达式测试工具](https://regexr.com/)
- [Regulex正则表达式可视化工具](https://jex.im/regulex)
- [any-rule正则表达式大全](https://github.com/any86/any-rule)
- [learn-regex](https://github.com/ziishaned/learn-regex)