考虑以下正则表达式,其中X是任何正则表达式。
X{n}|X{m}
此正则表达式将测试X发生的确切 n时间或m时间。
是否有一个正则表达式量词可以X准确地测试某个事件n或m时间?
没有一个量词表示“正好 m 或 n 次”。你这样做的方式很好。
另一种选择是:
X{m}(X{k})?
其中m < n和k是 的值n-m。
这是量词的完整列表(参考http://www.regular-expressions.info/reference.html):
?, ??- 0 或 1 次出现(??懒惰,?贪婪)*, *?- 任意数量的出现+, +?- 至少出现一次{n}- 确切地n发生{n,m}-n发生m,包容{n,m}?-n发生m,懒惰{n,}, {n,}?- 至少n发生要获得“恰好 N 或 M”,您需要编写两次量化的正则表达式,除非 m,n 是特殊的:
X{n,m}如果m = n+1(?:X{n}){1,2}如果m = 2n不,没有这样的量词。但我会对其进行重组/X{m}(X{m-n})?/以防止回溯中出现问题。
TLDR;(?<=[^x]|^)(x{n}|x{m})(?:[^x]|$)
看起来你想要“xn 次”或“xm 次”,我认为正则表达式的直译是(x{n}|x{m}).
这样的https://regex101.com/r/vH7yL5/1
或者,如果您可以拥有超过 m 个“x”的序列(假设 m > n),您可以添加 'following no "x"' 和 'followed by no "x",转换[^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
最后,为了匹配一个字符的远距离匹配,您可以在“no 'x' after”上添加正向向前看 (?=) 或在“no 'x' before”上添加正向向后看 (?<=),像这样:https ://regex101.com/r/mC4uX3/1
(?<=[^x]|^)(x{n}|x{m})(?:[^x]|$)
这样,您将只匹配您想要的确切数量的“x”。
很老的帖子,但我想贡献一些可能会有所帮助的东西。我已经完全按照问题中所述的方式进行了尝试,它确实有效,但有一个问题:数量的顺序很重要。考虑一下:
#[a-f0-9]{6}|#[a-f0-9]{3}
这将找到所有出现的十六进制颜色代码(它们的长度为 3 位或 6 位)。但是当我像这样翻转它时
#[a-f0-9]{3}|#[a-f0-9]{6}
它只会找到 3 位数字或 6 位数字的前 3 位数字。这确实是有道理的,Regex 专业人士可能会立即发现这一点,但对于许多人来说,这可能是一种特殊的行为。有一些高级的正则表达式功能可以避免这个陷阱,不管顺序如何,但并不是每个人都深入了解正则表达式模式。
看看 Enhardened 的回答,他们说倒数第二个表达式不会匹配它们之间只有一个字符的序列。有一种简单的方法可以在不使用前瞻/后视的情况下解决此问题,那就是将开始/结束字符替换为边界字符。这使您可以匹配包括开始/结束在内的单词边界。因此,适当的表达应该是:
(?:[^x]|\b)(x{n}|x{m})(?:[^x]|\b)
正如您在此处看到的:https ://regex101.com/r/oC5oJ4/2 。