正则表达式{m,n}是如何定义的?用Python工作?

正则表达式{m,n}是如何定义的?用Python工作?,python,regex,Python,Regex,从re模块的Python文档中: {m,n} 使生成的RE与前一个RE的m到n个重复相匹配,尝试匹配尽可能少的重复。这是前一个限定符的非贪婪版本。例如,在6个字符的字符串'aaaaaa'上,{3,5}将匹配5个'a'字符,而{3,5}将匹配5个'a'字符?将只匹配3个字符 我不知道这是怎么回事。这与{m}有何不同?我看不出有哪一种情况下,模式可以匹配超过m重复。如果一行中有m+1重复,那么也有m。我遗漏了什么?然而,一个正则表达式只包含a{3,5}和一个模式:a{3}将匹配相同的东西(即re.m

re
模块的Python文档中:

{m,n}

使生成的RE与前一个RE的m到n个重复相匹配,尝试匹配尽可能少的重复。这是前一个限定符的非贪婪版本。例如,在6个字符的字符串'aaaaaa'上,{3,5}将匹配5个'a'字符,而{3,5}将匹配5个'a'字符?将只匹配3个字符


我不知道这是怎么回事。这与
{m}
有何不同?我看不出有哪一种情况下,模式可以匹配超过
m
重复。如果一行中有
m+1
重复,那么也有
m
。我遗漏了什么?

然而,一个正则表达式只包含
a{3,5}
和一个模式:
a{3}
将匹配相同的东西(即
re.match(r'a{3,5},'aaaaaaa')。组(0)
re.match(r'a{3},'aaaaa')。组(0)
都将返回
'aaa'
),当您查看包含这两个元素的模式时,模式之间的差异变得很明显。假设您的模式是
a{3,5}?b
,则
aaab
aaaaab
,将匹配
aaaaab
。如果您只使用了
a{3}b
,那么只有
aaab
会得到匹配<代码>aaaab和
aaaaaab
不会


看看Shashank的答案,寻找更多的例子来消除这种差异,或者测试一下你自己。我发现这是一个很好的资源,可以用来测试python正则表达式。

Swankswashbuckler的答案描述了贪婪的版本。
使其不贪婪,这意味着它将尝试匹配尽可能少的项,这意味着

`re.match('a{3,5}?b', 'aaaab').group(0)` # returns `'aaaab'` 
但是


我认为通过以下例子可以看出两者之间的区别:

>>> re.findall(r'ab{3,5}?', 'abbbbb')
['abbb']
>>> re.findall(r'ab{3}', 'abbbbb')
['abbb']
这两次运行的结果与预期相同,但让我们看看一些差异

区别1:子模式上的范围量词允许您匹配包含该子模式的大范围模式。这样,如果使用精确的量词,您可以找到通常不会有匹配项的匹配项:

>>> re.findall(r'ab{3,5}?c', 'abbbbbc')
['abbbbbc']
>>> re.findall(r'ab{3}c', 'abbbbbc')
[]
区别2:贪婪并不一定意味着“匹配尽可能短的子模式”。实际上,这更像是“匹配最短的子模式,从最左侧的不匹配索引开始,该索引可能开始匹配”:

我认为正则表达式是一种构造,它使用指向字符串中索引的两个迭代器从左到右扫描字符串。第一个迭代器标记下一个可能模式的开始。第二个迭代器从第一个迭代器开始遍历子字符串的后缀,并尝试完成模式。只有当构造确定正则表达式模式不可能匹配从该索引开始的字符串时,第一个迭代器才会前进。因此,为您的量词定义一个范围将使得第一个迭代器将保持匹配子模式超过指定的最小值,即使量词是非贪婪的

非贪婪正则表达式将在模式停止时立即停止其第二个迭代器,但贪婪正则表达式将“保存”匹配模式的位置,并继续搜索更长的模式。如果找到较长的模式,则使用该模式;如果未找到,则使用先前保存在内存中的较短模式


这就是为什么你会看到'b{3,5}?c'和'bbbbc'可能令人惊讶的结果。尽管正则表达式是贪婪的,但在模式匹配失败之前,它永远不会推进其第一个迭代器,这就是为什么具有5个“b”字符的子字符串被非贪婪正则表达式匹配,即使它不是可匹配的最短模式

假设要搜索的字符串是: str=“aaaaa”

现在我们有patter=a{3,5} 它匹配的字符串是:{aaa,aaaa,aaaa} 但这里我们有字符串“aaaaa”,因为我们只有一个选项

现在假设我们有pattern=a{3,5}? 在这种情况下,它只匹配“aaa”而不是“AAAA”

因此,它采用尽可能少的项目,是非贪婪的

请尝试在以下位置使用联机正则表达式:


这将非常有帮助,我们会立即检查它匹配的内容和不匹配的内容

您考虑过设置一些测试用例并进行实验吗?你应该先这样做,然后如果你对结果感到困惑,在你的问题中贴上你想要匹配的内容。这只是你想要匹配的重复次数的一个范围,而不是一个精确的数字。注意,
{m,n}
{m,n}?
(注意
)有细微的不同。获取更多信息,请访问“regex non-greedy”。@ColonelThirtyTwo是的,我理解
{m,n}
{m,n}?
之间的区别,我在理解
{m}
{m,n}之间的区别时遇到了困难?
我不明白为什么有一个6票的答案不能回答问题。match将匹配两个字符串,不管它是否贪婪。这个答案是误导性的,会使IMO感到困惑。更好的办法是指出
A{3,5}
A{3,5}
模式与字符串“aaaaaa”之间的区别。谢谢。现在更正了,还有第二个错误也被更正了。编辑仍然没有真正显示出非贪婪和贪婪之间的区别。我建议显示
re.findall(r'a{3,5}?','a'*6)
re.findall(r'a{3,5}','a'*6)
第一个会找到两个匹配项,第二个只找到一个。是的。第一个案例匹配4个a,第二个匹配3个a。两个字符串都有4个a'OP询问
{m}
{m,n}之间的区别
>>> re.findall(r'ab{3,5}?c', 'abbbbbc')
['abbbbbc']
>>> re.findall(r'ab{3}c', 'abbbbbc')
[]
>>> re.findall(r'b{3,5}?c', 'bbbbbc')
['bbbbbc']
>>> re.findall(r'b{3}c', 'bbbbbc')
['bbbc']