# PCRE2常规语法参考手册
## 1. 基本字符匹配
### 1.1 普通字符
- `a`, `b`, `c` - 匹配对应的字符
**示例:**
- 文本: "hello"
- 表达式: `h`
- 预期结果: 匹配"h"
### 1.2 转义字符
- `\.` - 匹配句号字符
- `\$` - 匹配美元符号
- `\\` - 匹配反斜杠
**示例:**
- 文本: "price is $10.50"
- 表达式: `\$`
- 预期结果: 匹配"$"
## 2. 字符类(Character Classes)
### 2.1 预定义字符类
- `\d` - 匹配数字字符(0-9)
- `\D` - 匹配非数字字符
- `\w` - 匹配单词字符(字母、数字、下划线)
- `\W` - 匹配非单词字符
- `\s` - 匹配空白字符(空格、制表符、换行符等)
- `\S` - 匹配非空白字符
**示例:**
- 文本: "Hello World 123!"
- 表达式: `\d+`
- 预期结果: 匹配"123"
- 文本: "Hello World 123!"
- 表达式: `\w+`
- 预期结果: 匹配"Hello"
- 文本: "Hello World 123!"
- 表达式: `\s+`
- 预期结果: 匹配空格
### 2.2 自定义字符类
- `[abc]` - 匹配方括号中的任一字符
- `[^abc]` - 匹配不在方括号中的任一字符
- `[a-z]` - 匹配a到z之间的任一字符
- `[A-Z]` - 匹配A到Z之间的任一字符
- `[0-9]` - 匹配0到9之间的任一数字
**示例:**
- 文本: "hello"
- 表达式: `[aeiou]`
- 预期结果: 匹配"e"和"o"
- 文本: "hello"
- 表达式: `[^aeiou]`
- 预期结果: 匹配"h"、"l"、"l"
## 3. 量词(Quantifiers)
### 3.1 基本量词
- `*` - 匹配零次或多次
- `+` - 匹配一次或多次
- `?` - 匹配零次或一次
- `{n}` - 匹配恰好n次
- `{n,}` - 匹配至少n次
- `{n,m}` - 匹配n到m次
**示例:**
- 文本: "aaaa"
- 表达式: `a*`
- 预期结果: 匹配"aaaa"
- 文本: "aaaa"
- 表达式: `a+`
- 预期结果: 匹配"aaaa"
- 文本: "aa"
- 表达式: `a?`
- 预期结果: 匹配"a"(两次)
- 文本: "aaabbbccc"
- 表达式: `a{3}`
- 预期结果: 匹配"aaa"
- 文本: "aaabbbccc"
- 表达式: `b{2,4}`
- 预期结果: 匹配"bbb"
### 3.2 非贪婪量词
- `*?` - 非贪婪匹配零次或多次
- `+?` - 非贪婪匹配一次或多次
- `??` - 非贪婪匹配零次或一次
- `{n,m}?` - 非贪婪匹配n到m次
**示例:**
- 文本: "aaaa"
- 表达式: `a*?`
- 预期结果: 匹配空字符串(零次匹配)
- 文本: "aaaa"
- 表达式: `a+?`
- 预期结果: 匹配"a"(最小的一次匹配)
## 4. 占有量词(Possessive Quantifiers)
占有量词表示贪婪匹配且不允许回溯。与普通量词的主要区别在于:
- 普通量词(如`*`):如果后续模式匹配失败,会回溯并减少匹配的字符数
- 占有量词(如`*+`):一旦匹配成功,就不会回溯,即使后续模式匹配失败
### 4.1 语法
- `*+`, `++`, `?+`, `{n,m}+` - 在普通限定符后加`+`
### 4.2 区别详解
- `*` vs `*+`:
- `.*c` 在文本"abc"中会匹配"abc"(`.`匹配所有字符直到末尾,然后回溯直到找到`c`)
- `.*+c` 在文本"abc"中不会匹配任何内容(`.*+`匹配所有字符,不留下任何字符给`c`,且不会回溯)
**示例:**
- 文本: "abc"
- 表达式: `a.*c`
- 预期结果: 匹配"abc"(普通量词允许回溯)
- 文本: "abc"
- 表达式: `a.*+c`
- 预期结果: 不匹配(占有量词不回溯,`.*+`消耗了所有剩余字符)
- 文本: "aaaa"
- 表达式: `a++b`
- 预期结果: 不匹配(a++消耗所有a,没有剩余的给b)
- 文本: "aaaa"
- 表达式: `a+a`
- 预期结果: 不匹配(a+消耗所有a,没有剩余的给后面的a)
## 5. 锚点(Anchors)
### 5.1 位置锚点
- `^` - 匹配字符串开始
- `$` - 匹配字符串结束
- `\b` - 匹配单词边界
- `\B` - 匹配非单词边界
- `\A` - 匹配字符串开始(不受多行模式影响)
- `\Z` - 匹配字符串结束或行尾的换行符前
- `\z` - 匹配字符串绝对结束
- `\G` - 匹配第一次匹配的位置
**示例:**
- 文本: "hello world"
- 表达式: `^hello`
- 预期结果: 匹配"hello"
- 文本: "hello world"
- 表达式: `world$`
- 预期结果: 匹配"world"
- 文本: "hello world"
- 表达式: `\bwo\w+`
- 预期结果: 匹配"world"
## 6. 分组和捕获(Groups and Captures)
### 6.1 捕获分组
- `(abc)` - 创建一个捕获组
- `(?:abc)` - 创建一个非捕获组
**示例:**
- 文本: "hello world"
- 表达式: `(hello)\s+(world)`
- 预期结果: 匹配"hello world",第一个捕获组"hello",第二个捕获组"world"
- 文本: "hello world"
- 表达式: `(?:hello)\s+(world)`
- 预期结果: 匹配"hello world",只有第二个捕获组"world"
### 6.2 命名捕获分组
- `(?<name>...)` - Perl/PCRE2命名捕获组
- `(?'name'...)` - .NET命名捕获组(在我们的COM组件中自动转换为PCRE2语法)
- `(?P<name>...)` - Python命名捕获组
**注意:**
- .NET风格的 `(?'name'...)` 语法在我们的COM组件中会被自动转换为PCRE2支持的 `(?<name>...)` 语法
- 如果在VB6/VBScript中遇到错误(如错误80004005),建议直接使用 `(?<name>...)` 语法
**示例:**
- 文本: "John Smith"
- 表达式: `(?<first>\w+)\s+(?<last>\w+)`
- 预期结果: 匹配"John Smith",命名捕获组first="John",last="Smith"
## 7. 选择操作符(Alternation)
### 7.1 基本选择
- `|` - 或操作符,匹配左边或右边的模式
**示例:**
- 文本: "apple"
- 表达式: `apple|banana`
- 预期结果: 匹配"apple"
- 文本: "banana"
- 表达式: `apple|banana`
- 预期结果: 匹配"banana"
## 8. 转义序列(Escape Sequences)
### 8.1 非打印字符
- `\t` - 制表符
- `\n` - 换行符
- `\r` - 回车符
- `\f` - 换页符
- `\a` - 响铃符
- `\e` - ESC字符
**示例:**
- 文本: "hello\tworld"
- 表达式: `\t`
- 预期结果: 匹配制表符
### 8.2 十六进制和八进制
- `\xFF` - 十六进制字符
- `\123` - 八进制字符
**示例:**
- 文本: "A"
- 表达式: `\x41`
- 预期结果: 匹配"A"(十六进制41是A的ASCII码)
## 9. Unicode属性(Unicode Properties)
### 9.1 Unicode通用类别
- `\p{L}` - 任何类型的字母
- `\p{Lu}` - 大写字母
- `\p{Ll}` - 小写字母
- `\p{Nd}` - 十进制数字
- `\p{P}` - 任何标点符号
- `\p{S}` - 任何符号
- `\p{Z}` - 任何分隔符
### 9.2 Unicode脚本
- `\p{Arabic}` - 阿拉伯语文字
- `\p{Han}` - 汉字
- `\p{Latin}` - 拉丁文字
**示例:**
- 文本: "Hello 世界"
- 表达式: `\p{L}+`
- 预期结果: 匹配"Hello"和"世界"
## 10. POSIX字符类
### 10.1 POSIX类
- `[:alnum:]` - 字母和数字
- `[:alpha:]` - 字母
- `[:ascii:]` - ASCII字符
- `[:blank:]` - 空格和制表符
- `[:cntrl:]` - 控制字符
- `[:digit:]` - 数字
- `[:graph:]` - 图形字符
- `[:lower:]` - 小写字母
- `[:print:]` - 可打印字符
- `[:punct:]` - 标点符号
- `[:space:]` - 空白字符
- `[:upper:]` - 大写字母
- `[:word:]` - 单词字符(字母、数字、下划线)
- `[:xdigit:]` - 十六进制数字
**示例:**
- 文本: "Hello123"
- 表达式: `[[:alpha:]]+`
- 预期结果: 匹配"Hello"
- 文本: "Hello123"
- 表达式: `[[:digit:]]+`
- 预期结果: 匹配"123"
## 11. 特殊构造
### 11.1 注释
- `(?#comment)` - 模式中的注释
**示例:**
- 文本: "hello"
- 表达式: `h(?#this is a comment)ello`
- 预期结果: 匹配"hello"
### 11.2 扩展模式
- `(?x)` - 启用扩展模式,忽略空格和注释
**示例:**
- 文本: "abc123"
- 表达式: `(?x)abc 123` (在扩展模式下)
- 预期结果: 匹配"abc123"
## 12. 实际应用示例
### 12.1 电子邮件验证
- 文本: "user@example.com"
- 表达式: `\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b`
- 预期结果: 匹配"user@example.com"
### 12.2 IP地址验证
- 文本: "192.168.1.1"
- 表达式: `\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b`
- 预期结果: 匹配"192.168.1.1"
### 12.3 URL匹配
- 文本: "https://www.example.com"
- 表达式: `https?://[^\s/$.?#].[^\s]*`
- 预期结果: 匹配"https://www.example.com"
### 12.4 日期格式
- 文本: "2023-12-25"
- 表达式: `\d{4}-\d{2}-\d{2}`
- 预期结果: 匹配"2023-12-25"
## 13. 注意事项
1. 在字符类中,大部分元字符失去特殊意义,但仍需转义`]`和`^`
2. 转义字符在字符类中可能有不同的含义(如`\b`在字符类中表示退格符)
3. 量词作用于前面的原子元素,需要用括号分组以应用于多个字符
4. 某些字符类如`\d`、`\w`、`\s`在UTF模式下可能匹配更多字符
5. 不同语言的正则表达式实现可能存在细微差异
6. 在使用Unicode属性时,需要确保PCRE2编译时启用了Unicode支持
7. 关于命名捕获组语法,注意不同语言的差异:
- .NET 使用 `(?'name'...)` 语法
- Perl/PCRE2 使用 `(?<name>...)` 语法
- 我们的COM组件支持这两种语法的转换
'\K 断点,表示之前的所有匹配都不作数,只匹配\K之后的内容
'(\w+ )\K(\d+) "Hello 123" 只返回123
'(?<name>…) 命名捕获组Perl
'(?'name'…) 命名捕获组Perl & .NET
'(?P<name>…) 命名捕获组Python
'(?:…) 非捕获组,属于不返回捕获组
'(?|…) 重新编号捕获组,重新从1开始编号,属于不返回捕获组
Perl扩展字符类
'(?[...]) Perl扩展字符类基本语法
'(?[\p{Thai} & \p{Nd}]) Unicode 属性交集:匹配“泰国文字(Thai)且是十进制数字(Nd)”的字符
'(?[(x - y) & z]) 分组与运算:使用小括号 ( ) 对集合运算进行分组
' (?[(\d - [3]) & \p{Letter}])
'(?[ [^3] & \p{Nd} ]) 匹配除 3 之外的十进制数字
'(?[ [:alpha:] - [z] ]) 匹配除 z 之外的所有字母
'(?[ \d - [3] ]) \d 表示所有数字,减去 [3] 表示排除 3
'(?[ !\n & [:ascii:] ]) 转义字符:\n 表示换行符,! 表示补集;匹配所有 ASCII 字符,排除换行符
'集合运算符
' x|y, x+y 取并集(OR) [\p{L} + \d],匹配字母或数字
' x&y 取交集(AND) [\p{L} & \p{M}] 匹配既是字母又是组合标记的字符
' x-y 取差集(AND NOT) [\d - [3]] 匹配数字但不包括 3
' x^y 对称差集(XOR) [\p{L} ^ [a-z]] 匹配字母集合中除 a-z 之外的字符
' !x 取补集(NOT) 匹配非数字字符
捕获组引用
'(?R) 递归整个表达式
'(?n) 通过绝对编号引用捕获组
'(?+n) 通过相对编号引用捕获组
'(?-n) 通过相对编号引用捕获组
'(?&name) 通过名称引用捕获组 (Perl)
'(?P>name) 通过名称引用捕获组 (Python)
'\g<name> 通过名称引用捕获组 (Oniguruma)
'\g'name' 通过名称引用捕获组 (Oniguruma)
'\g<n> 通过绝对编号引用捕获组 (Oniguruma)
'\g'n' 通过绝对编号引用捕获组 (Oniguruma)
'\g<+n> 通过相对编号引用捕获组 (PCRE2扩展)
'\g'+n' 通过相对编号引用捕获组 (PCRE2扩展)
'\g<-n> 通过相对编号引用捕获组 (PCRE2扩展)
'\g'-n' 通过相对编号引用捕获组 (PCRE2扩展)
Copyright © 2025- vba.vip All Rights Reserved.