Регулярное выражение ровно n ИЛИ m раз


Рассмотрим следующее регулярное выражение, где X - это любое регулярное выражение.

X{n}|X{m}

Это регулярное выражение будет проверять, чтобы X происходило точно n или m раз.

Существует ли квантор регулярных выражений, который может проверять вхождение X точно n или m раз?

Author: Damien_The_Unbeliever, 2012-12-14

5 answers

Не существует единого квантора, который означал бы "ровно m или n раз". То, как вы это делаете, прекрасно.

Альтернативой является:

X{m}(X{k})?

Где m < n и k - значение n-m.

 63
Author: Mark Byers, 2012-12-14 08:10:58

Вот полный список кванторов (см. 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
  • ...
 39
Author: John Dvorak, 2012-12-14 08:16:33

Нет, такого квантора не существует. Но я бы изменил его на /X{m}(X{m-n})?/, чтобы предотвратить проблемы при возврате.

 18
Author: Bergi, 2012-12-14 08:12:45

ДВУ; (?<=[^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", которое вы хотите.

 1
Author: Enhardened, 2016-07-07 16:03:10

Взглянув на ответ Enhardened, они утверждают, что их предпоследнее выражение не будет соответствовать последовательностям только с одним символом между ними. Существует простой способ исправить это без использования look ahead/look behind, а именно заменить начальный/конечный символ символом границы. Это позволяет сопоставлять границы слов, которые включают начало/конец. Как таковое, соответствующее выражение должно быть:

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

Как вы можете видеть здесь: https://regex101.com/r/oC5oJ4/2.

 0
Author: rozza2058, 2018-05-08 12:13:23