php regex preg_match只允许某些关键字

时间:2011-07-29 12:49:56

标签: php regex preg-match

我正在尝试在IF语句中使用preg_match,如果字符串包含一些不允许的模板化函数,则返回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 :(得分:0)

不太确定你在这里尝试了什么,但是如果我要创建一个匹配单词列表(或者根据具体情况可能是函数名称)的正则表达式,我会做类似

的事情。
// 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那些不是的东西

然而,正如Álvaro所提到的,正则表达式可能并不是解决这个问题的最佳方法,而且无论代码的其余部分如何,将函数暴露出来都是非常危险的。如果你只需要匹配单词它应该工作正常,但因为它的函数调用任意参数......好吧。我不能真的推荐它:)

编辑:第一次,我在内爆字符串上使用preg_quote,但这当然只是转义管道字符,然后模式将无效。所以跳过preg_quote,但是请确保函数名称不包含任何可能搞乱最终模式的内容(例如,在破坏之前通过preg_quote 运行每个函数名称阵列)