混淆Python中正则表达式的用法

vic*_*icd 15 python regex

我对以下三种模式感到困惑,有人会更详细地解释它吗?

## IPython with Python 2.7.3
In [62]: re.findall(r'[a-z]*',"f233op")
Out[62]: ['f', '', '', '', 'op', '']  ## why does the last '' come out?

In [63]: re.findall(r'([a-z])*',"f233op")
Out[63]: ['f', '', '', '', 'p', '']  ## why does the character 'o' get lost?

In [64]: re.findall(r'([a-z]*)',"f233op")
Out[64]: ['f', '', '', '', 'op', '']  ## what's the different than line 63 above?
Run Code Online (Sandbox Code Playgroud)

woe*_*ler 15

例1

re.findall(r'[a-z]*',"f233op")
Run Code Online (Sandbox Code Playgroud)

此模式匹配小写字母字符的零个或多个实例.ZERO或更多部分在这里是关键,因为从字符串中的每个索引位置开始的任何匹配都与for 的匹配一样有效op.返回的最后一个空字符串是从字符串结尾开始的匹配(字符串之间的位置p和$(字符串结尾)).

例2

re.findall(r'([a-z])*',"f233op")
Run Code Online (Sandbox Code Playgroud)

现在,您将匹配由单个小写字母字符组成的字符组.将o不再返回,因为这是一个贪婪的搜索,最后有效的匹配组将被退回.因此,如果您将字符串更改为f233op12fre,e将返回最终结果,但不会返回前面的f或r.同样,如果你取出p字符串,你仍然会看到它o作为有效匹配返回.

相反,如果你试图通过添加一个?(例如.([a-z])*?)来使这个正则表达式非贪婪,那么返回的匹配集将全部是空字符串,因为没有任何东西的有效匹配具有更高的有效匹配优先级.

例3

re.findall(r'([a-z]*)',"f233op")
Run Code Online (Sandbox Code Playgroud)

匹配的字符没有什么不同,但现在您返回的是字符组而不是原始匹配.此正则表达式查询的输出将与您的第一个示例相同,但您会注意到,如果添加其他匹配组,您将突然看到每个匹配尝试的结果分组为元组:

IN : re.findall(r'([a-z]*)([0-9]*)',"f233op")
OUT: [('f', '233'), ('op', ''), ('', '')]  
Run Code Online (Sandbox Code Playgroud)

将其与相同的模式进行对比,减去括号(组),您将看到它们为什么重要:

IN : re.findall(r'[a-z]*[0-9]*',"f233op")
OUT: ['f233', 'op', ''] 
Run Code Online (Sandbox Code Playgroud)

也...

将像这样的正则表达式模式插入Regex图形生成器(如Regexplained)以查看模式匹配逻辑的工作方式非常有用.例如,作为为什么你的正则表达式总是返回空字符串匹配的解释,请看一下模式[a-z]*和之间的区别[a-z]+.

如果遇到问题,请不要忘记检查库的Python文档re,它们实际上给出了标准正则表达式语法的一个非常好的解释.


ala*_*air 6

  1. 你得到了决赛,''因为最后[a-z]*匹配空字符串.

  2. 'o'由于您已告知re.findall匹配组,并且每个组都有一个字符,因此该字符丢失.换句话说,你做的相当于

    m = re.match(r'([a-z])*', 'op')
    m.group(1)
    
    Run Code Online (Sandbox Code Playgroud)

    将返回'p',因为这是parens捕获的最后一件事(捕获组1).

  3. 同样,你是匹配组,但这次是多字符组.

  • 这仍然不能完全为我做.`o`去哪儿了?为什么不'['f','','','','o','p','']`? (2认同)
  • @mgilson由于组在正则表达式中匹配的方式.如果我匹配这样的东西:`([az])*`对一个字符串,那么组1的捕获值将是匹配的*last*实例.即匹配''foobar',我会得到''r'. (2认同)