写点什么

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:081861
用户头像

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

关注

评论

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

LLM 应用可观测性:从 Trace 视角展开的探索与实践之旅

阿里巴巴云原生

阿里云 云原生 可观测

ETH现货ETF流入量估算:会重演BTC现货ETF走势吗?

区块链软件开发推广运营

dapp开发 区块链开发 链游开发 公链开发 公链钱包开发

《Programming from the Ground Up》阅读笔记:p88-p94

codists

assembly 编程人

PIRF-405

Echo!!!

English

供配电学习笔记 day5

万里无云万里天

电力 工厂运维

供配电学习笔记 day6

万里无云万里天

电力 工厂运维

(已封装)电商API解析指南:深入理解店铺商品搜索结果

代码忍者

API Explorer API 编排 api 货币化 API 接口

记录一次Linux服务器被人使用SSH字典爆破

我再BUG界嘎嘎乱杀

Linux 网络安全 SSH 字典爆破

Spring高手之路21——深入剖析Spring AOP代理对象的创建

砖业洋__

Java spring aop

全网热议!GitHub发布的最简单的黑客入门教程,你值得拥有!

我再BUG界嘎嘎乱杀

黑客 网络安全 安全 网安

爱回收平台API:关键词搜索商品列表数据接口|爱回收平台数据采集

tbapi

爱回收 爱回收API 爱回收商品数据接口 爱回收商品列表数据接口 爱回收商品列表数据采集

初阶技能:Android 应用异常如何丰富线索

iofomo

android 移动端 开发技能

比 Xshell 还好用的 SSH 客户端,MobaXterm 太酷了!

源字节1号

小程序 开源 后端

演播室如何合理使用LED显示屏

Dylan

技术 活动 综艺节目 LED display LED显示屏

硅纪元视角 | 摩根大通拥抱AI:LLM Suite开启金融行业新篇章!

硅纪元

图解自定义 Dialog 对话框

chasel

什么是 CSRF?如何防止 CSRF 攻击?

我再BUG界嘎嘎乱杀

网络安全 安全 CSRF WEB安全 漏洞

基于RAG构建专业可信营销垂域大模型

东信营销科技

AI大模型 多模态大模型 检索增强技术RAG

Oracle JDK 8无缝更换为 Amazon Corretto 8

源字节1号

小程序 开源 后端

1688代采集运系统搭建:实现订单处理自动化

tbapi

1688代采系统 1688代采 逆向海淘系统 逆向海淘

客户在哪儿AI——做真正管用的大客户获客方案

客户在哪儿AI

ToB营销 活动营销 大客户营销

2024-07-27:用go语言,给定一个正整数数组,最开始可以对数组中的元素进行增加操作,每个元素最多加1。 然后从修改后的数组中选出一个或多个元素,使得这些元素排序后是连续的。 要求找出最多可以选

福大大架构师每日一题

福大大架构师每日一题

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