匹配第n个匹配项(不包括最后一个匹配项)

时间:2018-10-25 09:30:33

标签: regex regex-lookarounds

我对正则表达式有疑问。我不知道为什么我不能做以下事情。

例句:

"This is a test string with five t's"

我使用的正则表达式:

^(.*?(?=t)){3}

我希望正则表达式匹配以下内容。

"This is a test s"

但这不起作用,有人知道为什么吗?

2 个答案:

答案 0 :(得分:0)

正如@CertainPerformance所说,.*将匹配模式中的零个或多个字符,但是您使用其懒惰版本.*?。 量词的惰性版本将使其与尽可能少的字符匹配。 如果使用与空字符串匹配的量词,则总会导致长度为零的匹配。

您需要改用+量词`,以防止空字符串匹配。

Python演示:

>>> import re
>>> s = "This is a test string with five t's"
>>> r = r'^(.+?(?=t)){3}'
>>> re.match(r, s)
<_sre.SRE_Match object; span=(0, 16), match='This is a test s'>

答案 1 :(得分:0)

这里的意思是整个.*?(?=t)组模式可以匹配一个空字符串。它在第一个t之前停止,并且不能“跳过去”,因为当前瞻模式(非消耗模式)匹配时,它保持在原处。

您不能这样做,必须消耗(并移动正则表达式索引)至少一个字符。

针对这种具体情况的替代解决方案是

^(?:[^t]*t){2}[^t]*

请参见regex demo^(?:[^t]*t){2}[^t]*与字符串(^)的开头匹配,然后消耗两次({2})除{{1}以外的任何字符}(t后跟[^t]*,然后再次消耗两次(t以外的{2}以外的任何字符。

或者,一个一般情况的解决方案(如果t是一个多字符字符串):

t

请参见another regex demo^(?:.*?t){2}(?:(?!t).)* 模式匹配任意0个字符的两次出现,并尽可能少地匹配,直到第一个(?:.*?t){2},然后t匹配任意0个字符的不开始的字符(?:(?!t).)*个char序列。