[英]Regex exactly n OR m times
考虑以下正则表达式,其中X
是任何正则表达式。
X{n}|X{m}
此正则表达式将测试X
恰好出现n
次或m
次。
是否有一个正则表达式量词可以测试X
恰好n
次或m
次出现?
没有单一的量词表示“恰好 m 次或 n 次”。 你这样做的方式很好。
另一种选择是:
X{m}(X{k})?
其中m < n
和k
是nm
的值。
这是量词的完整列表(参考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{mn})?/
以防止回溯问题。
很老的帖子,但我想贡献一些可能有帮助的东西。 我已经完全按照问题中所述的方式进行了尝试,它确实有效,但有一个问题:数量的顺序很重要。 考虑一下:
#[a-f0-9]{6}|#[a-f0-9]{3}
这将找到所有出现的十六进制颜色代码(它们的长度为 3 位或 6 位)。 但是当我像这样翻转它时
#[a-f0-9]{3}|#[a-f0-9]{6}
它只会找到 3 位数字或 6 位数字的前 3 位数字。 这确实有道理,正则表达式专家可能会立即发现这一点,但对许多人来说,这可能是一种特殊的行为。 无论顺序如何,有一些高级 Regex 功能都可以避免此陷阱,但并非每个人都深入了解 Regex 模式。
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"' 和 'following 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”。
看看 Enhardened 的回答,他们说他们的倒数第二个表达式不会匹配它们之间只有一个字符的序列。 有一种简单的方法可以在不使用前瞻/后视的情况下解决这个问题,那就是用边界字符替换开始/结束字符。 这使您可以匹配包括开始/结束在内的单词边界。 因此,适当的表达应该是:
(?:[^x]|\\b)(x{n}|x{m})(?:[^x]|\\b)
正如您在此处看到的: https : //regex101.com/r/oC5oJ4/2 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.