if(preg_match("/" . $filter . "/i", $node)) { echo $node; }
Этот код фильтрует переменную, чтобы решить, отображать ее или нет. Примером записи для фильтра $ будет «офис» или «164 (. *) 976».
Я хотел бы знать, есть ли простой способ сказать: если $ filter не соответствует в $ node. В виде регулярного выражения?
Итак … не «if (! Preg_match», а больше $ filter = «! Office» или «! 164 (. *) 976», но тот, который работает?
Это можно сделать, если вы определенно хотите использовать «отрицательное регулярное выражение» вместо простого инвертирования результата положительного регулярного выражения:
if(preg_match("/^(?:(?!" . $filter . ").)*$/i", $node)) { echo $node; }
будет соответствовать строке, если она не содержит regex / substring в $filter
.
Объяснение: (прием в качестве нашей строки примера)
^ # Anchor the match at the start of the string (?: # Try to match the following: (?! # (unless it's possible to match office # the text "office" at this point) ) # (end of negative lookahead), . # Any character )* # zero or more times $ # until the end of the string
Отрицательное утверждение (?!...)
– это то, что вы ищете.
Чтобы исключить определенную строку из любой точки объекта, вы можете использовать этот метод двойного утверждения:
preg_match('/(?=^((?!not_this).)+$) (......)/xs', $string);
Это позволяет указать произвольное (……) основное регулярное выражение. Но вы можете просто оставить это, если хотите только запретить строку.
Ответ № 2 от mario – правильный ответ, и вот почему:
Сначала, чтобы ответить на комментарий Джастина Моргана,
Мне любопытно, знаете ли вы, какова эффективность этого в отличие от подхода preg_match ()? Я не в месте, где я могу проверить их обоих. – Джастин Морган Apr 19 '11 в 21:53
Рассмотрим логику ворот на мгновение.
Когда отменять preg_match (): при поиске соответствия и вы хотите, чтобы условие было 1) истинно для отсутствия желаемого регулярного выражения, или 2) false для присутствующего регулярного выражения.
Когда использовать отрицательное утверждение в регулярном выражении: при поиске соответствия и вы хотите, чтобы условие было истинным, если строка ТОЛЬКО соответствует регулярному выражению и не выполняется, если что-то еще найдено. Это необходимо, если вам действительно нужно протестировать нежелательные символы, позволяя пропускать разрешенные символы.
Отрицание результата (preg_match () === 1) проверяет только наличие регулярного выражения. Если требуется «бар», а номера не разрешены, следующее не будет работать:
if (preg_match('bar', 'foo2bar') === 1) { echo "found 'bar'"; // but a number is here, so fail. } if (!pregmatch('[0-9]', 'foobar') === 1) { echo "no numbers found"; // but didn't test for 'bar', so fail. }
Итак, чтобы действительно протестировать несколько регулярных выражений, начинающий тестировал бы с помощью нескольких вызовов preg_match () … мы знаем, что это очень любительский способ сделать это.
Итак, Op хочет протестировать строку для возможных регулярных выражений, но условное выражение может передаваться только как истинное, если строка содержит хотя бы один из них. Для большинства простых случаев достаточно просто отказаться от preg_match (), но для более сложных или расширенных шаблонов регулярных выражений это не будет. Я буду использовать свою ситуацию для более реалистичного сценария:
Предположим, вы хотите иметь форму пользователя для имени человека, в частности фамилию. Вы хотите, чтобы ваша система принимала все письма независимо от случая и места размещения, принимала дефисы, принимала апострофы и исключала все остальные символы. Мы знаем, что соответствие регулярному выражению для всех нежелательных символов – это первое, о чем мы думаем, но представьте, что вы поддерживаете UTF-8 … это много символов! Ваша программа будет почти такой же большой, как таблица UTF-8, только на одной строке! Меня не волнует, какое оборудование у вас есть, у вашего серверного приложения есть конечный предел в том, как долго будет команда, не говоря уже о пределе 200 скобок в скобках, поэтому таблица символов ENTIRE UTF-8 (минус [AZ], [az ], -, and ') слишком длинная, неважно, что сама программа будет ОГРОМНОЙ!
Поскольку мы не будем использовать if (! Preg_match ('. # \\ $ \% … это может быть довольно длинным и невозможным оценить … в строке, чтобы увидеть, является ли строка плохим, мы должны вместо этого проверить проще, с отрицательным обратным выражением утверждения в регулярном выражении, а затем отрицать общий результат, используя:
<?php $string = "O'Reilly-Finlay"; if (preg_match('/?![az\'-]/i', $string) === 0) { echo "the given string matched exclusively for regex pattern"; // should not work on error, since preg_match returns false, which is not an int (we tested for identity, not equality) } else { echo "the given string did not match exclusively to the regex pattern"; } ?>
Если бы мы искали только регулярное выражение [az \ '-] / i, все, что мы говорим, это «строка соответствия, если она содержит ЛЮБОЙ из этих вещей», поэтому плохие символы не тестируются. Если мы отрицаем функцию, мы говорим «return false, если мы найдем совпадение, содержащее любую из этих вещей». Это тоже не так, поэтому нам нужно сказать: «return false, если мы будем соответствовать НИЧЕГО не в регулярном выражении», что делается с помощью lookahead. Я знаю, что колокола уходят в чью-то голову, и они думают о расширении подстановочных знаков … нет, взгляд не делает этого, он просто делает отрицание в каждом матче и продолжает. Таким образом, он проверяет первый символ для регулярного выражения, если он совпадает, он перемещается, пока не найдет несоответствие или конец. После его завершения все, что было найдено, не соответствует регулярному выражению, возвращается в массив совпадений или просто возвращает 1. Короче говоря, assert negative в regex 'a' является противоположным совпадению регулярного выражения 'b', где 'b' содержит ВСЕ ЕЩЕ не совместимы с 'a'. Отлично, когда «b» будет нечестивым.
Примечание: если в моем регулярном выражении есть ошибка, я извиняюсь … Я использую Lua в течение последних нескольких месяцев, поэтому я могу смешивать правила регулярных выражений. В противном случае '?!' является правильным синтаксисом lookahead для PHP.