Регулярное выражение ровно n ИЛИ m раз
Рассмотрим следующее регулярное выражение, где X
- это любое регулярное выражение.
X{n}|X{m}
Это регулярное выражение будет проверять, чтобы X
происходило точно n
или m
раз.
Существует ли квантор регулярных выражений, который может проверять вхождение X
точно n
или m
раз?
5 answers
Не существует единого квантора, который означал бы "ровно 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})?/
, чтобы предотвратить проблемы при возврате.
ДВУ; (?<=[^x]|^)(x{n}|x{m})(?:[^x]|$)
Похоже, вы хотите "x n раз" или "x m раз", я думаю, что буквальный перевод в регулярное выражение будет (x{n}|x{m}).
Вот так https://regex101.com/r/vH7yL5/1
Или, в случае, когда у вас может быть последовательность более m "x" (при условии, что m>n), вы можете добавить "после " без "x"" и "после "без "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
Наконец, чтобы сопоставить удаленное совпадение с одним символом, вы можете добавьте позитивный взгляд вперед (?=) на "нет "x "после" или позитивный взгляд назад (?https://regex101.com/r/mC4uX3/1
(?<=[^x]|^)(x{n}|x{m})(?:[^x]|$)
Таким образом, вы будете соответствовать только точному количеству "x", которое вы хотите.
Взглянув на ответ Enhardened, они утверждают, что их предпоследнее выражение не будет соответствовать последовательностям только с одним символом между ними. Существует простой способ исправить это без использования look ahead/look behind, а именно заменить начальный/конечный символ символом границы. Это позволяет сопоставлять границы слов, которые включают начало/конец. Как таковое, соответствующее выражение должно быть:
(?:[^x]|\b)(x{n}|x{m})(?:[^x]|\b)
Как вы можете видеть здесь: https://regex101.com/r/oC5oJ4/2.