PHP регулярное выражение preg_match разрешить только определенные ключевые слова - PullRequest
1 голос
/ 29 июля 2011

Я пытаюсь использовать preg_match в операторе IF и возвращать false, если строка содержит некоторые шаблонные функции, которые не разрешены.

Вот некоторые примеры допустимых шаблонных функций:

{function="nl2br($value.field_30)"}
{function="substr($value.field_30,0,250)"}
{function="addslashes($listing.photo.image_title)"}
{function="urlencode($listing.link)"}
{function="AdZone(1)"}

Они смешаны с HTML и т. Д.

Теперь я бы хотел, чтобы этот оператор preg_match возвращал true, если регулярное выражение соответствует формату кода, но не содержит одно из разрешенных ключевых слов функции:

if (preg_match('(({function=)(.+?)(nl2br|substr|addslashes|urlencode|AdZone)(.+?)\})',$string)) {
    // found a function not allowed
} else {
    // string contains only allowed functions or doesn't contain functions at all
}

Кто-нибудь знает, как это сделать?

1 Ответ

0 голосов
/ 29 июля 2011

Не совсем уверен, что вы пытаетесь здесь, но если бы я сделал регулярное выражение, соответствующее списку слов (или именам функций в зависимости от обстоятельств), я бы сделал что-то вроде

// add/remove allowed stuff here
$allowed = array( 'nl2br', 'substr', 'addslashes' );

// make the array into a branching pattern
$allowed_pattern = implode('|', $allowed);

// the entire regexp (a little stricter than yours)    
$pattern = "/\{function=\"($allowed_pattern)\((.*?)\)\"\}/";

if( preg_match($pattern, $string, $matches) ) {
    # string DOES contain an allowed function
    # The $matches things is optional, but nice. $matches[1] will be the function name, and
    # $matches[2] will be the arguments string. Of course, you could just do a
    # preg_replace_callback() on everything instead using the same pattern...
} else {
    # No allowed functions found
}

Массив $allowed упрощает добавление / удаление разрешенных имен функций, а регулярные выражения более строги в отношении фигурных скобок, кавычек и общего синтаксиса, что, вероятно, является хорошей идеей.

Но, прежде всего, переверните ветки if..else или используйте !. preg_match предназначено для совпадения в строке, а не для сопоставления, которого там нет. Так что вы не можете заставить его вернуть true за то, что не там

Тем не менее, как упомянул Альваро, регулярные выражения, вероятно, не лучший способ сделать это, и довольно рискованно представлять такие функции, независимо от остальной части кода. Если вам просто нужно сопоставить слова, это должно работать нормально, но так как это вызовы функций с произвольными аргументами ... хорошо. Я не могу порекомендовать это :)

Редактировать: В первый раз я использовал preg_quote для развернутой строки, но это, конечно, просто экранирует символы канала, и тогда шаблон не будет работать. Так что пропустите preg_quote, но затем просто убедитесь, что имена функций не содержат ничего, что могло бы испортить окончательный шаблон (например, пропустите каждое имя функции через preg_quote до взрыва массива)

...