简体   繁体   English

PHP正则表达式preg_match只允许某些关键字

[英]php regex preg_match allow only certain keywords

I'm trying use preg_match in an IF statement and return false if a string contains some templated functions not allowed. 我正在尝试在IF语句中使用preg_match,如果字符串包含某些不允许的模板化函数,则返回false。

Here are some example templated functions allowed: 这是允许的一些示例模板函数:

{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)"}

These are mixed in with html etc. 这些与html等混合在一起。

Now I'd like this preg_match statement to return true if regex matches the code format but didn't contain one of the allowed function keywords: 现在,我希望此preg_match语句在regex与代码格式匹配但不包含允许的功能关键字之一的情况下返回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
}

Does anyone know how to do this? 有谁知道如何做到这一点?

Not quite sure what you're trying here, but if I were to make a regexp that matched a list of words (or function names as the case may be), I'd do somthing like 不太确定您要在这里尝试什么,但是如果我要使正则表达式与单词列表(或函数名,视情况而定)匹配,我会做些类似的事情

// 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
}

The $allowed array makes it easier to add/remove allowed function names, and the regexp is stricter about the curly brackets, quotes and general syntax, which is probably a good idea. $allowed数组使添加/删除允许的函数名称更加容易,而regexp对大括号,引号和常规语法更为严格,这可能是一个好主意。

But first of all, flip the if..else branches, or use a ! 但首先,翻转if..else分支,或使用! . preg_match is meant for, well, matching stuff in the string, not for matching stuff that isn't in there. preg_match是为了匹配字符串中的内容,而不是匹配不存在的内容。 So you can't really get it to return true for something that isn't there 因此,对于某些存在的内容,您实际上无法使其返回true

Still, as Álvaro mentioned, regexps probably aren't the best way to go about this, and it is pretty risky to have functions exposed like that, no matter the rest of the code. 但是,正如Álvaro所提到的,正则表达式可能不是解决此问题的最佳方法,并且不管其他代码如何,暴露这样的函数都是非常冒险的。 If you just needed to match words it should work fine, but since it's function calls with arbitrary arguments... well. 如果您只需要匹配单词,它应该可以正常工作,但是由于它是带有任意参数的函数调用……很好。 I can't really recommend it :) 我真的不能推荐它:)

Edit: First time around, I used preg_quote on the imploded string, but that of course just escapes the pipe characters, and then the pattern won't work. 编辑:第一次,我在插入的字符串上使用了preg_quote ,但是当然只转义了竖线字符,然后该模式将不起作用。 So skip preg_quote , but then just be sure that function names don't contain anything that might mess up the final pattern (eg run each function name through preg_quote before imploding the array) 因此,跳过preg_quote ,但是只要确保函数名称不包含任何可能弄乱最终模式的内容即可(例如, 插入数组之前通过preg_quote运行每个函数名称)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM