小能豆

在 python re 模块中'[ab]+' 是否等于'(a|b)+'?

py

我认为 pat1 = ‘[ab]’ 和 pat2 = ‘a|b’ 在 Python(python2.7, windows) ‘re’ 模块中与正则表达式模式具有相同的功能。但我对 ‘[ab]+’ 和 ‘(a|b)+’ 感到困惑,它们是否具有相同的功能,如果不是,您能解释一下细节吗?

'''
Created on 2012-9-4

@author: melo
'''

import re
pat1 = '(a|b)+'
pat2 = '[ab]+'
text = '22ababbbaa33aaa44b55bb66abaa77babab88'

m1 = re.search(pat1, text)
m2 = re.search(pat2, text)
print 'search with pat1:', m1.group()
print 'search with pat2:', m2.group()

m11 = re.split(pat1, text)
m22 = re.split(pat2, text)
print 'split with pat1:', m11
print 'split with pat2:', m22

m111 = re.findall(pat1, text)
m222 = re.findall(pat2, text)
print 'findall with pat1:', m111
print 'findall with pat2:', m222

输出如下:

search with pat1: ababbbaa
search with pat2: ababbbaa
split with pat1: ['22', 'a', '33', 'a', '44', 'b', '55', 'b', '66', 'a', '77', 'b', '88']
split with pat2: ['22', '33', '44', '55', '66', '77', '88']
findall with pat1: ['a', 'a', 'b', 'b', 'a', 'b']
findall with pat2: ['ababbbaa', 'aaa', 'b', 'bb', 'abaa', 'babab']

为什么’pat1’和’pat2’不同,它们有什么区别?’pat1’实际上可以匹配什么样的字符串?


阅读 17

收藏
2024-11-11

共1个答案

小能豆

在 Python 的re模块中,pat1 = '(a|b)+'和都匹配和的pat2 = '[ab]+'序列,但它们在捕获结果和分离匹配的方式上表现不同。a``b

模式解释

  1. pat1 = '(a|b)+':此模式使用带竖线的括号|,表示交替分组。表达式表示“匹配或”。以下表达式允许此组重复一次或多次。因此,它匹配或的序列但会独立捕获组中的每个或。(a|b)``a``b``+``a``b``a``b
  2. pat2 = '[ab]+':此模式使用方括号,即字符类。表示“匹配 或的[ab]任何字符”。下面的意思是字符类可以重复一次或多次。 这将匹配 和 的序列,但将它们视为单个组,而不会单独捕获每个元素。a``b``+``[ab]``a``b

行为差异

让我们看看中的每个方法如何与和re交互。pat1``pat2

re.search

  • re.search(pat1, text)和都返回和字符re.search(pat2, text)序列中的第一个匹配项。a``b
  • 输出ababbbaa针对两种模式。

对于re.search,两种模式的行为类似,因为它们只是寻找第一个匹配并将其作为整体返回。

re.split

  • re.split(pat1, text)
  • a在或每次出现时进行拆分b,因为由于组内交替,(a|b)+将每个a和视为单独的匹配。b
  • 每个a或都b充当一个分裂点。
  • 输出['22', 'a', '33', 'a', '44', 'b', '55', 'b', '66', 'a', '77', 'b', '88']
  • re.split(pat2, text)
  • 通过任意连续的ab字符序列进行匹配和拆分,将它们视为单个匹配。
  • 输出['22', '33', '44', '55', '66', '77', '88']

这种差异是因为(a|b)+将每个ab视为拆分的可能匹配,而将s 和s[ab]+的整个运行视为拆分的单个匹配。a``b

re.findall

  • re.findall(pat1, text)
  • 查找所有a或的序列b,但仅返回每个序列中的最后一个匹配字符(因为findall仅捕获括号中的匹配组)。
  • 输出['a', 'a', 'b', 'b', 'a', 'b']
  • re.findall(pat2, text)
  • 查找并返回a和的所有连续序列b
  • 输出['ababbbaa', 'aaa', 'b', 'bb', 'abaa', 'babab']

在 中re.findall(a|b)+匹配每个ab作为序列中的单独元素,但只返回每组的最后一个字符(由于分组捕获规则),而匹配和 的[ab]+整个块。a``b

概括

  • (a|b)+:在组内交替,捕获每个匹配项ab将其作为单独的匹配项。
  • [ab]+:与单个 s 序列ab整个 s 匹配的字符类。

这样:

  • (a|b)+如果您需要捕获序列中的各个元素,特别是当您有兴趣单独捕获每个项目时,这很有用。
  • [ab]+如果您只需要匹配as 和bs 块而无需单独捕获每个元素,则效率更高。
2024-11-11