php regex preg_match 只允许某些关键字

Posted

技术标签:

【中文标题】php regex preg_match 只允许某些关键字【英文标题】:php regex preg_match allow only certain keywords 【发布时间】:2011-10-15 22:39:56 【问题描述】:

我正在尝试在 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等混合在一起。

现在,如果 regex 匹配代码格式但不包含允许的函数关键字之一,我希望此 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

有人知道怎么做吗?

【问题讨论】:

不确定正则表达式是否是最好的工具。也许它们可以与老式的标记器和解析器结合使用:-?不过,无论该功能的潜在风险如何,这个问题都很好:) 我打算这样做,但为了保持代码干净,我想我先在这里要求一个简单的 if 语句解决方案。 【参考方案1】:

不太清楚你在这里尝试什么,但如果我要创建一个匹配单词列表(或函数名称,视情况而定)的正则表达式,我会做类似

// 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 运行每个函数名称​​在 内爆数组之前)

【讨论】:

以上是关于php regex preg_match 只允许某些关键字的主要内容,如果未能解决你的问题,请参考以下文章

PHP(RegEx)电话号码验证

PHP(RegEx)邮政编码验证

PHP(RegEx)IP地址验证

如何在PHP中preg_match一个可以为NULL的变量?

PHP(RegEx)电子邮件地址验证

PHP/REGEX:获取括号内的字符串