写点什么

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

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

关注

评论

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

【Flutter 专题】11 图解 ListView 的多种绑定方式

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 11月日更

Vue进阶(幺捌叁):IE9兼容性问题-数据初始化问题

No Silver Bullet

Vue 11月日更

阿里P8十年摸爬滚打,告诉你上古程序猿为何反对使用Redis?

Java 程序员 后端

阿里P8架构师汇总了史上101个最牛逼的Java技术点

Java 程序员 后端

dart系列之:dart语言中的异常

程序那些事

flutter dart 程序那些事 11月日更

我终于知道,中国互联网是怎么弯道超车,干翻美国了!

博文视点Broadview

阿里2020首发一百多道Java高级岗面试题(含答案)

Java 程序员 后端

阿里P8面试官梳理的2020年999道大厂高频Java面试题(附答案)

Java 程序员 后端

遇到Java内存溢出(OOM)时,这样排查

Java 程序员 后端

重走JAVA之路(五):面试又被问线程池原理?教你如何反击(1)

Java 程序员 后端

闲下来的学习时光

Java 程序员 后端

华为全球技术服务引领行业数智创新,共赢未来

阿里P6程序员的Java之路-或许起点不高,但我从未停止我的脚步

Java 程序员 后端

阿里P7告诉你SpringBoot如何防止重复提交?

Java 程序员 后端

阿里P8大牛整理的300页图解网络知识+计算机底层操作系统

Java 程序员 后端

一个简单的UserCase,带你认识openLooKeng的行级权限控制

LooK

大数据 openLooKeng

金三银四助力面试-手把手轻松读懂HashMap源码

Java 程序员 后端

闭关2个月肝完Java7大核心知识(分布式+JVM+Java基础+算法

Java 程序员 后端

逼着面试官问了我ArrayList和LinkedList的区别,他对我彻底服了

Java 程序员 后端

阿里-美团-字节面试官必问的Mysql锁机制,你真的明白吗

Java 程序员 后端

阿里P8大佬终于把自己珍藏多年581页JavaJDK9学习笔记分享出来了

Java 程序员 后端

安装企业级的dokuwiki文档系统

小鲍侃java

11月日更

阿里P8直接甩我一份Java笔记、面试宝典,当我看到目录的一瞬间,简直怀疑人生!

Java 程序员 后端

阿里P8级大神经验分享,怎样成为一个优秀的架构师?(1)

Java 程序员 后端

透过根源从而探究红黑树的本质,究竟二叉树是什么神仙鬼怪?

Java 程序员 后端

拥有一台服务器后,我竟然这么酷?

老表

Python Linux web开发 云服务器 跟老表学云服务器

重走JAVA之路(五):面试又被问线程池原理?教你如何反击

Java 程序员 后端

阿里Java架构师春招面试高频600题:集合+JVM+Redis+并发

Java 程序员 后端

阿里P8大牛透出,入职阿里必备12套Java面试题,适合从校招到社招

Java 程序员 后端

通过AOP和自定义注解实现请求日志收集功能

Java 程序员 后端

Python爬虫120例之第20例,1637、一路商机网全站加盟数据采集

梦想橡皮擦

11月日更

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