拓展阅读¶
正则¶
注:以下正则语法如需在 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
会被该正则匹配。
正则表达式的代价¶
为了支持复杂语法,现在的正则表达式引擎一般使用回溯搜索的方法来进行匹配。对于某些特定的正则,攻击者可以构造出能够让其执行很长时间的字符串,从而导致系统崩溃。
相关介绍:乱用正则引发的惨案