一个使用纯 Swift 实现的正则表达式引擎
再次尝试 V2 版本,使用 DFA (确定有限状态自动机) 代替 NFA (非确定有限状态自动机) 以获得类似 grep 的性能
为了避免编译开销,可以创建一个 Regex
实例
// Compile the expression
let regex = try! Regex(pattern: "[a-zA-Z]+")
let string = "RegEx is tough, but useful."
// Search for matches
let words = regex.match(string)
/*
words = [
RegexMatch(match: "RegEx", groups: []),
RegexMatch(match: "is", groups: []),
RegexMatch(match: "tough", groups: []),
RegexMatch(match: "but", groups: []),
RegexMatch(match: "useful", groups: []),
]
*/
如果编译开销不是问题,可以使用 =~
运算符来匹配字符串
let fourLetterWords = "drink beer, it's very nice!" =~ "\\b\\w{4}\\b" ?? []
/*
fourLetterWords = [
RegexMatch(match: "beer", groups: []),
RegexMatch(match: "very", groups: []),
RegexMatch(match: "nice", groups: []),
]
*/
默认情况下,Global
标志处于激活状态。 要更改哪些标志处于激活状态,请在模式的开头添加 /
,并在末尾添加 /<flags>
。 可用标志如下
g
Global
- 允许匹配多个结果
i
Case Insensitive
- 大小写不敏感匹配
m
Multiline
- ^
和 $
也匹配行的开头和结尾
// Global and Case Insensitive search
let regex = try! Regex(pattern: "/\\w+/ig")
模式 |
描述 |
支持 |
. |
[^\n\r] |
|
[^] |
[\s\S] |
|
\w |
[A-Za-z0-9_] |
|
\W |
[^A-Za-z0-9_] |
|
\d |
[0-9] |
|
\D |
[^0-9] |
|
\s |
[\ \r\n\t\v\f] |
|
\S |
[^\ \r\n\t\v\f] |
|
[ABC] |
集合中的任何一个字符 |
|
[^ABC] |
不在集合中的任何字符 |
|
[A-Z] |
范围内的任何字符 (包含边界) |
|
模式 |
描述 |
支持 |
^ |
字符串的开头 |
|
$ |
字符串的结尾 |
|
\b |
单词边界 |
|
\B |
非单词边界 |
|
模式 |
描述 |
支持 |
\0 |
八进制转义字符 |
|
\00 |
八进制转义字符 |
|
\000 |
八进制转义字符 |
|
\xFF |
十六进制转义字符 |
|
\uFFFF |
Unicode 转义字符 |
|
\cA |
控制字符 |
|
\t |
制表符 |
|
\n |
换行符 |
|
\v |
垂直制表符 |
|
\f |
换页符 |
|
\r |
回车符 |
|
\0 |
\0 |
|
\. |
. |
|
\\ |
\ |
|
\+ |
+ |
|
\* |
* |
|
\? |
? |
|
\^ |
^ |
|
\$ |
$ |
|
\{ |
{ |
|
\} |
} |
|
\[ |
[ |
|
\] |
] |
|
\( |
( |
|
\) |
) |
|
\/ |
/ |
|
| |
` |
` |
模式 |
描述 |
支持 |
分组和环视 |
(ABC) |
|
捕获组 |
(<name>ABC) |
|
\1 |
命名捕获组 |
|
\k<name> |
命名反向引用 |
|
(?:ABC) |
非捕获组 |
|
(?=ABC) |
正向先行断言 |
|
(?!ABC) |
负向先行断言 |
|
(?<=ABC) |
正向后行断言 |
|
(?<!ABC) |
负向后行断言 |
|
模式 |
描述 |
支持 |
+ |
一个或多个 |
|
* |
零个或多个 |
|
? |
可选 |
|
{n} |
n 个 |
|
{,} |
与 * 相同 |
|
{,n} |
n 个或更少 |
|
{n,} |
n 个或更多 |
|
{n,m} |
n 到 m 个 |
|
模式 |
描述 |
支持 |
+? |
一个或多个 |
|
*? |
零个或多个 |
|
?? |
可选 |
|
{n}? |
n 个 |
|
{,n}? |
n 个或更少 |
|
{n,}? |
n 个或更多 |
|
{n,m}? |
n 到 m 个 |
|
模式 |
描述 |
支持 |
| |
匹配之前的所有内容或者之后的所有内容 |
|
模式 |
描述 |
支持 |
i |
大小写不敏感 |
|
g |
全局 |
|
m |
多行 |
|
(类似于之前)
- 词法分析器 (将字符串输入转换为 Token)
- 解析器 (将 Token 转换为 NFA)
- 编译器 (将 NFA 转换为 DFA)
- 优化器 (简化 DFA (例如
char(a), char(b)
-> string(ab)
) 以获得更好的性能)
- 引擎 (使用 DFA 匹配输入字符串)
Swift 将 \r\n
视为单个 Character
。 使用 \n\r
来同时拥有两者。