Python中正则表达式的使用

2.7.15、3.4.9、3.5.6rc1、3.6.5rc1和3.7.0之前的python在pop3lib的apop()和difflib.IS_LINE_JUNK方法中容易遭受灾难性的回溯。攻击者可能利用此缺陷导致拒绝服务。(CVE-2018-1060-1061)

因为python的这个漏洞涉及正则表达式,于是研究了下它的规则和使用。
参考:https://www.runoob.com/python3/python3-reg-expressions.html

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。
Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。
re 模块使 Python 语言拥有全部的正则表达式功能。
compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。
它的匹配规则大致如图:



正则表达式模式和实例

了解匹配规则后,我们来看一看具体代码:

-    timestamp = re.compile(br'\+OK.*(<[^>]+>)')
+    timestamp = re.compile(br'\+OK.[^<]*(<.*>)')

代码中给出的正则表达式,套用以上规则来尝试解析一下。
减号行的正则表达式,匹配出来的结果基本是这样的:


减号行timestamp匹配规则

加号行的正则表达式匹配出的结果如下图:


加号行timestamp匹配规则

减号行的匹配规则可以在“ <>”之前匹配多个“ <”,这在pop3的通信方式中会使服务器无法识别匹配的开始位置,并且连续匹配会增加耗时,可能超出限制导致程序无法响应。 使用加号行的表达式就避免了此错误。

再来看一个例子:

 import re
 
-def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match):
+def IS_LINE_JUNK(line, pat=re.compile(r"\s*(?:#\s*)?$").match):
     r"""
     Return 1 for ignorable line: iff `line` is blank or contains a single '#'.

减号行匹配出来是这样的:


减号行IS_LINE_JUNK匹配规则

加号行匹配出来是这样,如图:

加号行IS_LINE_JUNK匹配规则

这两个正则表达式的结果其实很相似,用等效的非脆弱正则表达式(r“ \ s *(?:#\ s *)?$”)来替换第一行,末尾允许匹配#号,以更好地过滤python的行注释。

模式字符串使用特殊的语法来表示一个正则表达式,在使用时需要注意以下几点:

  • 字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。
  • 多数字母和数字前加一个反斜杠时会拥有不同的含义。
  • 标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。
  • 反斜杠本身需要使用反斜杠转义。
  • 由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'\t',等价于 \t )匹配相应的特殊字符。

.

*引用转载本文需注明出处

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。