Создание условного регулярного выражения

#php #regex

#php #регулярное выражение

Вопрос:

Я создаю API и хочу реализовать опцию фильтрации, поэтому я хочу проверить выражение с помощью регулярного выражения. это выражение, отправленное в запросе.

 filter[price] = gt.5 and lt.10
 

Правила: первые символы представляют используемый оператор пример:

 gt = '>'
ge = '>='
lt = '<'
le = '<='
eq = '='
ne = '<>'
like = 'like'
ilike = 'ilike'
 

тогда есть точка для разделения сравниваемого значения, и, возможно, будет другое выражение, разделенное операторами «и» или «или».

Это регулярное выражение, которое я создал

 $re = '/([a-z]{2,5}.[w0-9] )(s)*(?(2)(and|or)2 ([a-z]{2,5}.[w0-9] ))/i';
 

Я хочу, чтобы регулярное выражение принимало как действительное следующие случаи и чтобы я считал недействительным любой другой случай, отличный от этих

 case 1: gt.5 (valid)
case 2: gt.5 and lt.10 (valid)
case 3: gt.5 and lt.10 or eq.5 (valid)
 

когда я тестирую регулярное выражение, оно работает для обоих случаев, но оно также соответствует для следующих случаев, но их следует считать недействительными.

 case 4: gt.5lt.10 (should be invalid)
case 5: gt.5and (should be invalid)
case 6: gt.5..lt.10 (should be invalid)
 

Комментарии:

1. Первое, что вам нужно исправить, это отсутствующий /x флаг и читаемость.

Ответ №1:

Что вы могли бы сделать вместо использования предложения if, так это необязательно повторить вторую часть с and and or для сопоставления нескольких частей и использовать якоря для предотвращения частичных совпадений.

Обратите внимание, что это w также соответствует цифре 0-9. В данных примера после точки есть цифры, поэтому вы могли бы просто использовать d вместо preventing для сопоставления gt.5and

  ^[a-z]{2,5}.d (?:h (?:and|or)h [a-z]{2,5}.d )*$
 

Демонстрация регулярных выражений

Вы могли бы сделать эту часть [a-z]{2,5} более точной, используя изменение, в котором перечислены все параметры (?:g[te]|l[te]eq|ne|i?like)


Более конкретным вариантом может быть использование чередования и повторное использование подшаблона (?1) , чтобы сделать его немного более кратким.

 ^([gl][te]|eq|ne|i?like).d (?:h (?:and|or)h (?1).d )*$
 

Объяснение

  • ^ Начало строки
  • ([gl][te]|eq|ne|i?like) Сопоставьте любую из альтернатив
  • .d Сопоставьте 1 . и 1 цифры
  • (?: Не группа захвата
    • h (?:and|or)h Сопоставьте любой and или or между 1 горизонтальными символами пробела
    • (?1).d Повторите первый подшаблон и сопоставьте . и 1 цифры
  • )* Закройте группу и повторите 0 раз, чтобы также разрешить одно gt.5
  • $ Конец строки

Демонстрация регулярных выражений

Комментарии:

1. [gl][te] чтобы уменьшить первые две ветви