• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

Python中re模块的用法概览

模块re提供了对正则表达式的支持。
除标准文档外,Andrew Kuchling撰写的文章“Regular Expression HOWTO”(https://docs.python.org/3/howto/regex.html)也是很有用的Python正则表达式学习资料。

  1. 正则表达式是什么
    正则表达式是可匹配文本片段的模式。最简单的正则表达式为普通字符串,与它自己匹配。换而言之,正则表达式'python'与字符串'python'匹配。你可使用这种匹配行为来完成如下工作:在文本中查找模式,将特定的模式替换为计算得到的值,以及将文本分割成片段。

  2. 通配符
    正则表达式可与多个字符串匹配,你可使用特殊字符来创建这种正则表达式。例如,句点与除换行符外的其他字符都匹配,因此正则表达式'.ython'与字符串'python'和'jython'都匹配。它还与'qython'、'+ython'和' ython'(第一个字符为空格)等字符串匹配,但不与'cpython'、'ython'等字符串匹配,因为句点只与一个字符匹配,而不与零或两个字符匹配。
    句点与除换行符外的任何字符都匹配,因此被称为通配符(wildcard)。

  3. 对特殊字符进行转义
    普通字符只与自己匹配,但特殊字符的情况完全不同。例如,假设要匹配字符串'python.org',可以直接使用模式'python.org'吗?可以,但它也与'pythonzorg'匹配,这可能不是你想要的结果。要让特殊字符的行为与普通字符一样,可对其进行转义:像对字符串中的引号进行转义时所做的那样,在它前面加上一个反斜杠。因此,在这个示例中,可使用模式'python\.org',它只与'python.org'匹配。
    请注意,为表示模块re要求的单个反斜杠,需要在字符串中书写两个反斜杠,让解释器对其进行转义。换而言之,这里包含两层转义:解释器执行的转义和模块re执行的转义。实际上,在有些情况下也可使用单个反斜杠,让解释器自动对其进行转义,但请不要这样依赖解释器。如果你厌烦了两个反斜杆,可使用原始字符串,如r'python.org'。

  4. 字符集
    匹配任何字符很有用,但有时你需要更细致地控制。为此,可以用方括号将一个子串括起,创建一个所谓的字符集。这样的字符集与其包含的字符都匹配,例如'[pj]ython'与'python'和'jython'都匹配,但不与其他字符串匹配。你还可使用范围,例如'[a-z]'与a~z的任何字母都匹配。你还可组合多个访问,方法是依次列出它们,例如'[a-zA-Z0-9]'与大写字母、小写字母和数字都匹配。请注意,字符集只能匹配一个字符。要指定排除字符集,可在开头添加一个字符,例如'[abc]'与除a、b和c外的其他任何字符都匹配。
    3.1 字符集中的特殊字符
    一般而言,对于诸如句点、星号和问号等特殊字符,要在模式中将其用作字面字符而不是正则表达式运算符,必须使用反斜杠对其进行转义。在字符集中,通常无需对这些字符进行转义,但进行转义也是完全合法的。然而,你应牢记如下规则。
    3.1.1 脱字符(^)位于字符集开头时,除非要将其用作排除运算符,否则必须对其进行转义。换而言之,除非有意为之,否则不要将其放在字符集开头。
    3.1.2 同样,对于右方括号(])和连字符(-),要么将其放在字符集开头,要么使用反斜杠对其进行转义。实际上,如果你愿意,也可将连字符放在字符集末尾。

  5. 二选一和子模式
    需要以不同的方式处理每个字符时,字符集很好,但如果只想匹配字符串'python'和'perl',该如何办呢?使用字符集或通配符无法指定这样的模式,而必须使用表示二选一的特殊字符:管道字符(|)。所需的模式为'python|perl'。然而,有时候你不想将二选一运算符用于整个模式,而只想将其用于模式的一部分。为此,可将这部分(子模式)放在圆括号内。对于前面的示例,可重写为'p(ython|erl)'。请注意,单个字符也可称为子模式。

  6. 可选模式和重复模式
    通过在子模式后面加上问号,可将其指定为可选的,即可包含可不包含。例如,下面这个不太好懂的模式:
    r'(http://)?(www.)?python.org'
    只与下面这些字符串匹配:
    'http://www.python.org'
    'http://python.org'
    'www.python.org'
    'python.org'
    对于这个示例,需要注意如下几点。
    5.1 我对句点进行了转义,以防它充当通配符。
    5.2 为减少所需的反斜杠数量,我使用了原始字符串。
    5.3 每个可选的子模式都放在圆括号内。
    5.4 每个可选的子模式都可以出现,也可以不出现。
    问号表示可选的子模式可出现一次,也可不出现。还有其他几个运算符用于表示子模式可重复多次。
    5.5 (pattern):pattern可重复0、1或多次。
    5.6 (pattern)+:pattern可重复1或多次。
    5.7 (pattern){m,n}:模式可重复m~n次。
    例如,r'w
    .python.org'与'www.python.org'匹配,也与'.python.org'、'ww.python.org'和'wwwwwww.python.org'匹配。同样,r'w+.python.org'与'w.python.org'匹配,但与'.python.org'不匹配,而只与r'w{3,4}.python.org'与'www.python.org'和'wwww.python.org'匹配。
    在这里,术语匹配指的是与整个字符串匹配,而函数match(参见表10-9)只要求模式与字符串开头匹配。

  7. 字符串的开头和末尾
    到目前为止,讨论的都是模式是否与整个字符串匹配,但也可查找与模式匹配的子串,如字符串'www.python.org'中的子串'www'与模式'w+'匹配。像这样查找字符串时,有时在整个字符串开头或末尾查找很有用。例如,你可能想确定字符串的开头是否与模式'ht+p'匹配,为此可使用脱字符('')来指出这一点。例如,'ht+p'与'http://python.org'和'htttttp://python.org'匹配,但与'www.http.org'不匹配。同样,要指定字符串末尾,可使用美元符号($)。
    完整的正则表达式运算符清单请参阅Python库中的Regular Expression Syntax部分。

  8. 模块re的内容
    模块re包含多个使用正则表达式的函数,表10-9描述了其中最重要的一些。
    模块re中一些重要的函数
    |函数| 描述 |
    | ---- | ---- |
    |compile(pattern[, flags]) |根据包含正则表达式的字符串创建模式对象|
    |search(pattern, string[, flags])| 在字符串中查找模式|
    |match(pattern, string[, flags]) |在字符串开头匹配模式|
    |split(pattern, string[, maxsplit=0]) |根据模式来分割字符串|
    |findall(pattern, string) |返回一个列表,其中包含字符串中所有与模式匹配的子串|
    |sub(pat, repl, string[, count=0]) |将字符串中与模式pat匹配的子串都替换为repl|
    |escape(string)| 对字符串中所有的正则表达式特殊字符都进行转义|

函数re.compile将用字符串表示的正则表达式转换为模式对象,以提高匹配效率。调用search、match等函数时,如果提供的是用字符串表示的正则表达式,都必须在内部将它们转换为模式对象。通过使用函数compile对正则表达式进行转换后,每次使用它时都无需再进行转换。
模式对象也有搜索/匹配方法,因此re.search(pat, string)(其中pat是一个使用字符串表示的正则表达式)等价pat.search(string)(其中pat是使用compile创建的模式对象)。编译后的正则表达式对象也可用于模块re中的普通函数中。函数re.search在给定字符串中查找第一个与指定正则表达式匹配的子串。如果找到这样的子串,将返回MatchObject(结果为真),否则返回None(结果为假)。鉴于返回值的这种特征,可在条件语句中使用这个函数,如下所示:
if re.search(pat, string):
print('Found it!')
然而,如果你需要获悉有关匹配的子串的详细信息,可查看返回的MatchObject。下一节将更详细地介绍MatchObject。
函数re.match尝试在给定字符串开头查找与正则表达式匹配的子串,因此re.match('p','python')返回真(MatchObject),而re.match('p', 'www.python.org')返回假(None)。
函数match在模式与字符串开头匹配时就返回True,而不要求模式与整个字符串匹配。如果要求与整个字符串匹配,需要在模式末尾加上一个美元符号。美元符号要求与字符串末尾匹配,从而将匹配检查延伸到整个字符串。
函数re.split根据与模式匹配的子串来分割字符串。这类似于字符串方法split,但使用正则表达式来指定分隔符,而不是指定固定的分隔符。例如,使用字符串方法split时,可以字符串', '为分隔符来分割字符串,但使用re. split时,可以空格和逗号为分隔符来分割字符串。

some_text = 'alpha, beta,,,,gamma delta'
re.split('[, ]+', some_text)
['alpha', 'beta', 'gamma', 'delta']
如果模式包含圆括号,将在分割得到的子串之间插入括号中的内容。例如,re.split('o(o)','foobar')的结果为['f', 'o', 'bar']。
从这个示例可知,返回值为子串列表。参数maxsplit指定最多分割多少次。
re.split('[, ]+', some_text, maxsplit=2)
['alpha', 'beta', 'gamma delta']
re.split('[, ]+', some_text, maxsplit=1)
['alpha', 'beta,,,,gamma delta']
函数re.findall返回一个列表,其中包含所有与给定模式匹配的子串。例如,要找出字符串包含的所有单词,可像下面这样做:
pat = '[a-zA-Z]+'
text = '"Hm... Err -- are you sure?" he said, sounding insecure.'
re.findall(pat, text)
['Hm', 'Err', 'are', 'you', 'sure', 'he', 'said', 'sounding', 'insecure']
要查找所有的标点符号,可像下面这样做:
pat = r'[.?-",]+'
re.findall(pat, text)
['"', '...', '--', '?"', ',', '.']
请注意,这里对连字符(-)进行了转义,因此Python不会认为它是用来指定字符范围的(如a-z)。
函数re.sub从左往右将与模式匹配的子串替换为指定内容。请看下面的示例:
pat = '{name}'
text = 'Dear {name}...'
re.sub(pat, 'Mr. Gumby', text)
'Dear Mr. Gumby...'
有关如何更有效地使用这个函数,请参阅随后的一节。
re.escape是一个工具函数,用于对字符串中所有可能被视为正则表达式运算符的字符进行转义。使用这个函数的情况有:字符串很长,其中包含大量特殊字符,而你不想输入大量的反斜杠;你从用户那里获取了一个字符串(例如,通过函数input),想将其用于正则表达式中。下面的示例说明了这个函数的工作原理:
re.escape('www.python.org')
'www\.python\.org'
re.escape('But where is the ambiguity?')
'But\ where\ is\ the\ ambiguity\?'
在表10-9中,注意到有些函数接受一个名为flags的可选参数。这个参数可用于修改正则表达式的解读方式。有关这方面的详细信息,请参阅“Python库参考手册”中讨论模块re的部分。

posted on 2022-08-31 22:59  SOC验证工程师  阅读(324)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3