2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

Jeff Moser 解释.NET 正则表达式的工作方式

  • 2009-04-02
  • 本文字数:1017 字

    阅读完需:约 3 分钟

Jeff Moser 发表了一篇对.NET 中正则表达式工作方式的深入解析。他的文章谈及了微软实现中的一些核心操作原理,如编译正则表达式时使用的机器码。

他首先透露,最近使用的 15 个正则表达式会被缓存起来。对于那些只使用 1 到 2 个正则表达式的小型的应用程序,这意味着没有必要每次都创建一个 Regex 对象。

在编译正则表达式的时候,首先会通过一个扫描器(scanner)来生成(emit)一个 RegexTree。它的叶子节点就好像一种略加扩展的源代码,而下一步便是把它转换为正则表达式引擎所使用的机器码。

这些工作由 EmitFragment 函数完成,其中包含了大约 250 行的 switch 语句。这个函数把 RegexTree 打散成“碎片”再将它们转化为相对简单的 RegexCode

[…]

这些工作生成一个用于描述 RegexCode“操作码”及其参数的整数数组。例如,你可以看到一些例如“ Setrep ”的指令携带了一些字符串参数。这些参数指向了一个字符串表中的偏移量。这就是为什么说,正如我们之前看到的那样,把所有的东西打包成那些不规则字符串是很重要的原因。这是唯一可以传递指令信息的方法。

把代码数组分解之后,我们可以看到:

索引

指令

操作码 / 参数

字符串表的引用

描述

复制代码
[Lazybranch](http://www.koders.com/csharp/fidF4B2B64D471D5B7401063DE2054CB33F28BDA026.aspx#L73)

23

复制代码
延迟扩展至偏移量为 21 的 [Stop](http://www.koders.com/csharp/fidF4B2B64D471D5B7401063DE2054CB33F28BDA026.aspx#L91) 指令。

1

复制代码
21
2

Setmark

31

复制代码
把我们当前的状态放入栈中以便稍后进行回溯。

3

Multi

12

复制代码
对字符串表中的第 0 项(即“http://”)进行一次多字符匹配。

4

复制代码
"http://"

5

Setmark

31

复制代码
把我们当前的状态放入栈中以便稍后进行回溯。

6

Setrep

2

复制代码
对于字符串表中位置为 1 的集合(即\[^\\s/\])进行长度为 1 的反复匹配。

7

复制代码
1

“\x1\x2\x1\x2F\x30\x64”

8

复制代码
1
9

Setloop

5

复制代码
在最多为 Int32.MaxValue 次的循环中对\[^\\s/\] 集合进行匹配。

10

复制代码
1

“\x1\x2\x1\x2F\x30\x64”

11

复制代码
2147483647
12

Capturemark

32

复制代码
捕获组#1,即最近一次 Setmark 所标记的位置,到当前位置的字符串。

13

复制代码
1
14
-1
15

Oneloop

3

复制代码
在最多为 1 次的循环中匹配 Unicode 字符 47

16

复制代码
47
17
1
18

Capturemark

32

复制代码
捕获组#0,即第一次 Setmark 所标记的位置,到当前位置的字符串。

19

复制代码
20
-1
21

Stop

40

复制代码
停止匹配。

可以看到,正则表达式已经被转化为一个稍后可供运行的简单“程序”。

Jeff Moser 的博客中描述了有关这个过程的更多信息。他的文章还讨论了:

  • 前缀优化
  • 解释器
  • 回溯
  • 已知错误

查看英文原文: Jeff Moser’s How .NET Regular Expressions Really Work

2009-04-02 21:081881
用户头像

发布了 157 篇内容, 共 61.9 次阅读, 收获喜欢 6 次。

关注

评论

发布
暂无评论
发现更多内容

阿里云 EMAS Serverless 重磅发布

hum建应用专家

云原生

【LeetCode】合并区间Java题解

Albert

LeetCode 8月月更

企业数字化转型,如何实现业务部门与算法部门共同探索模型开发优化

ModelWhale

数据分析 工作流 数字化转型 业务思维 协同开发

封仲淹:OceanBase社区版4.0未来畅想

OceanBase 数据库

从InfluxDB到TDengine,阳光氢能为什么会做出这个选择?

TDengine

数据库 tdengine 时序数据库

开源一夏 | 如何在 JavaScript 中创建虚拟键盘

海拥(haiyong.site)

JavaScript 开源 前端 8月月更

MSE 费芮新金融行业标杆案例

阿里巴巴中间件

阿里云 微服务 云原生

「数澈软件」获5300万元种子轮融资,构建新一代软件供应链防火墙

SEAL安全

软件供应链安全

为什么 DevOps 会失败?

飞算JavaAI开发助手

ArkID 企业级开源 IDaaS/IAM 统一身份认证授权管理解决方案

龙归科技

开源项目 iam SSO Idaas

云原生数据库白皮书,发布!

华为云开发者联盟

数据库 云原生 后端 华为云 白皮书

SAP Fiori Launchpad Tile,UI5 应用,和 PFCG Role 的对应关系

汪子熙

SAP Fiori Launchpad ui5 8月月更

企业如何将自身的数字技术及研究成果快速对外发布应用

ModelWhale

数字化转型 部署 应用模型 对外接口 协同开发

SAP AMDP 介绍 - ABAP 托管的 HANA 数据库过程

汪子熙

数据库 SAP abap 8月月更 AMDP

精妙绝伦!10年阿里工作经验总结出这份亿级高并发系统设计手册,真的太强了!

退休的汤姆

Java、 面经 社招 Java工程师 秋招

产品和管理必备技能 Top 5

宇宙之一粟

产品 领导力 8月月更

Go-Excelize API源码阅读(十七)——GetPageLayout、SetPageMargins

Regan Yue

Go 开源 源码解析 8月日更 8月月更

即时通讯安全篇(十):IM聊天系统安全手段之通信连接层加密技术

JackJiang

网络安全 https 网络编程 即时通讯 SSL/TLS

企业引进外部专家合作开发时,如何保证数字资产既开放又安全?

ModelWhale

数字化转型 数据安全 资产安全 技术专家 协同开发

Spring Security + Vue + Flowable 怎么玩?

江南一点雨

Java spring springsecurity flowable

使用 OpenTelemetry 零代码修改接收 SkyWalking 追踪数据

Daocloud 道客

云原生 可观测性 Skywalking OpenTelemetry

2022 OceanBase数据库大赛开启,30W奖金等你来拿!

OceanBase 数据库

字节内部MySQL宝典意外流出!堪称数据库的天花板

退休的汤姆

Java、 面经 Java工程师 秋招 MySQL 数据库

【有奖评测局】阿里云容器镜像 ACR 测评团限时招募中!

阿里巴巴中间件

阿里云 云原生 容器镜像

芯声智能亮相亚洲智能穿戴展,智能头盔声学方案为骑手保驾护航

硬科技星球

ModelBox开发体验:使用YOLOv3做口罩检测

华为云开发者联盟

人工智能 ModelBox

企业如何跨部门实现模型应用全生命周期管理

ModelWhale

数字化转型 应用模型 迭代管理 跨部门沟通 算法模型

开源一夏 | STM32对接涂鸦wifi模块项目(智能插座-开源)

矜辰所致

开源 stm32 WiFi物联网智能插座 8月月更 涂鸦智能

如何做好分支管理,保证高效CI/CD?

华为云开发者联盟

git 开发

创建第一个 Cypress 应用后使用命令行 npx Cypress open 报错的原因分析

汪子熙

前端开发 自动化测试 Cypress web开发 8月月更

J2EE进阶(三)struts2 <s:action>标签的用法及Spring在web.xml中的配置

No Silver Bullet

spring Struts2 8月月更 <s:action>

Jeff Moser解释.NET正则表达式的工作方式_.NET_Jonathan Allen_InfoQ精选文章