#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]
чтобы уменьшить первые две ветви