跳转至

拓展阅读

正则

注:以下正则语法如需在 grep 中使用,需要加上参数 -P,表示使用 Perl 语法。

懒惰和贪婪

使用 * + 的时候默认是贪婪模式,即尽可能匹配更多的子表达式。在 * + 之后加上 ? 变为懒惰模式,即尽可能匹配更少的子表达式。

例如:123456456

贪婪:1.+6 -> 123456456

懒惰:1.+?6 -> 123456

后向引用

后向引用可以将之前匹配到的具体内容再次利用。在正则表达式中,() 以及它们包含的内容为一个分组,每个分组默认拥有一个组号。

组号分配规则:

  • 0 代表整个表达式
  • 从左至右,按左括号的出现顺序分配,第一个为 1,第二个为 2,以此类推
  • 扫描两遍,第一次只分配未命名的组,第二次只分配命名的组。即任意命名组的组号都大于未命名的组号

示例

\b(\w+)\b\s+\1\b 可以用来匹配用空白字符分割的两个重复的单词(例如 linux linux),其中 \1 是对组号为 1 的组 (\w+) 的引用。

\b(?'Word'\w+)\b\s+\k'Word'\b 也可以起到同样的效果,其中 ?'Word' 用于命名组,\k'Word' 用于引用组。

零宽断言

零宽断言用于查找某些内容进行定位,但内容并不放入匹配结果,就像 \b ^ $ 的定位一样。(?=exp) 用于匹配表达式 exp 前面的位置,(?<=exp) 用于匹配后面的位置。

示例

\b\w+(?=ing\b) 可以匹配 ing 结尾的单词前面的部分。例如 going 中的 go 会被该正则匹配。

(?<=\bre)\w+\b 可以匹配 re 开开头的单词的后面一部分。例如 revue 中的 vue 会被该正则匹配。

正则表达式的代价

为了支持复杂语法,现在的正则表达式引擎一般使用回溯搜索的方法来进行匹配。对于某些特定的正则,攻击者可以构造出能够让其执行很长时间的字符串,从而导致系统崩溃。

相关介绍:乱用正则引发的惨案