xxleyi / learning_list

聚集自己的学习笔记
10 stars 3 forks source link

什么是正则表达式? #285

Open xxleyi opened 3 years ago

xxleyi commented 3 years ago

到底什么是正则表达式呢?我尝试给一个清晰的描述。

首发即刻:

image

修正后文字版全文:

大部分人或许并不关心何为正则表达式,但我个人比较喜欢厘清这种 what 问题。

正则表达式之前对我来说就是用于指定字符串模式,为此需要皱着眉头面对各种奇奇怪怪的符号,转义,捕获,分组,甚至反向引用,零宽断言,然后小心翼翼的施展魔法。我的心态是尽量不用它。

这并不是好事情,但我确实有点害怕正则,也没摸到门路。

最近事情起了转机,由于学习词法解析,从代码文本到 tokens 串这一步完美对应正则语言及其实现。这让我有机会从零到一重新认识正则语言,发现严格意义上的正则有着几条非常清晰的规则:

  1. 空集是合法的正则语言
  2. 空字符也是合法的正则语言,一般用 ε 表示
  3. 正则语言会有一套有限个数的字符集,比如 a b c
  4. 支持将两个子表达式串联,比如 RS
  5. 支持两个子表达式的并集,比如 R|S
  6. 支持克林星,表示无限重复,如 R*

有且仅有这些。那问题来了,平时使用的正则表达式为何明显比这些规则复杂很多呢?

大概有两类原因:

一类是简写 shorthands,像 ? + [1-9] 等等这类都可以用以上规则表达,只是比较繁琐,使用又很频繁,所以有了简写。

另一类值得重点关注,就是本身不属于严格意义上的正则表达式,但对于指定字符串模式来说又很有必要。这类就是一些扩展,确实不能用以上规则表达。

据我目前的了解,此类扩展主要就两个,一个是反向引用,(.+)\1 这种可以匹配 wewe 和 hahahaha 的模式。另一个是零宽断言,主要是简单的 ^ 和 $,以及复杂的环视。

B 站视频: https://www.bilibili.com/video/BV1H5411n7Y2/

总结:所谓“正则”就是六个规则加若干扩展。