正则表达式正好n次或m次


105

请看下面的正则表达式,这里X任何正则表达式。

X{n}|X{m}

该正则表达式将测试确切X发生的时间或时间。 nm

是否有一个正则表达式量词可以测试的发生X恰好nm次?


X不会。一般情况下m,您会得到两次最好的出现n
约翰·德沃夏克

如果这是我的问题,我将尝试使用正则表达式反向引用,并从开始(X)\1{n-1}(?:\1{m-n-1})。我知道这X至少匹配一次,但只是开始尝试这一简单的操作,然后使用lookaheads或lookbehinds代替即可进行优化(X)
凌晨

Answers:


91

没有单个量词的意思是“正好是m或n次”。您的操作方式很好。

一种替代方法是:

X{m}(X{k})?

其中m < nk是的值n-m


67

这是量词的完整列表(请参阅http://www.regular-expressions.info/reference.html):

  • ???-0或1次出现(??懒惰,?贪婪)
  • **?-任何数量的事件
  • ++?-至少发生一次
  • {n}- n确实发生
  • {n,m}- nm出现次数,包容
  • {n,m}?- nm出现次数,懒惰
  • {n,}{n,}?-至少n发生

要获得“恰好是N或M”,您需要两次编写量化的正则表达式,除非m,n特殊:

  • X{n,m} 如果 m = n+1
  • (?:X{n}){1,2} 如果 m = 2n
  • ...

1
为什么?:在if m = 2n示例中需要?似乎没有它,对我来说一切正常。
erb 2015年

7
@erb(如果忽略了)?:,该组将成为捕获组。除了正则表达式引擎无需记住其他内容外,如果您在此之后捕获组,则它们的ID也会更改。如果使用正则表达式进行替换,则必须调整替换。
John Dvorak 2015年


3

TLDR; (?<=[^x]|^)(x{n}|x{m})(?:[^x]|$)

看起来您想要“ xn次”或“ xm次”,我认为对正则表达式的字面翻译应该是(x{n}|x{m}). 这样https://regex101.com/r/vH7yL5/1

或者,在一个情况下,在这里可以具有大于M“×”更多的序列(假定M> N),则可以添加“以下没有‘×’”和“随后没有‘×’,翻译到[^x](x{n}|x{m})[^x]但是这将假设在您的“ x”之后和之后始终有一个字符。如您所见:https : //regex101.com/r/bB2vH2/1

您可以将其更改为(?:[^x]|^)(x{n}|x{m})(?:[^x]|$),表示为“没有'x'或行尾”和“没有'x'或行尾”。但是仍然不会匹配两个序列,并且两个序列之间只有一个字符(因为第一个匹配将要求后面有一个字符,第二个匹配将前面有一个字符),如下所示:https : //regex101.com/r/ oC5oJ4 / 1

最后,要匹配一个字符的远距离匹配,您可以在“后不加x”前添加正视(?=),或在“后不加x”前添加正视(?<=),像这样:https : //regex101.com/r/mC4uX3/1

(?<=[^x]|^)(x{n}|x{m})(?:[^x]|$)

这样,您将只匹配所需的确切数量的“ x”。


1

看一看Enhardened的答案,他们指出倒数第二个表达式不会匹配仅包含一个字符的序列。有一种简单的方法可以解决此问题,而无需使用向前/向后看,而是用边界字符替换开始/结束字符。这使您可以与包括开始/结束在内的单词边界进行匹配。因此,适当的表达应为:

(?:[^x]|\b)(x{n}|x{m})(?:[^x]|\b)

如您所见:https : //regex101.com/r/oC5oJ4/2


1
太酷了,我不熟悉正则表达式如何处理边界。该方法的唯一问题是使用非标准边界时。看一下故事:regex101.com/r/j0nkeo/1regex101.com/r/4Ix7Dr/1
强化时间为

1
@Enhardened-很好,这似乎是多个匹配组重叠的问题。在这种情况下,您需要使用后视。
rozza2058

1

很老的帖子,但是我想提供一些帮助。我已经按照问题中所述的方法进行了尝试,并且确实起作用,但是有一个陷阱:数量的顺序很重要。考虑一下:

#[a-f0-9]{6}|#[a-f0-9]{3}

这将查找所有出现的十六进制颜色代码(它们长3或6位数)。但是当我像这样翻转它时

#[a-f0-9]{3}|#[a-f0-9]{6}

它只会找到3位数字或6位数字的前3位。这确实是有道理的,并且Regex专业人士可能会立即发现这一点,但是对于许多人来说,这可能是一种特殊的行为。有一些高级的Regex功能可以避免此陷阱,而不管顺序如何,但并不是每个人都沉迷于Regex模式。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.