为了个人使用和工作,我编写了各种正则表达式来查找PHP中的所有变量。我的正则表达式的目的是出于安全原因,特别是VET脚本和插件。表达式如下:
\${1,1}[\w]+[" +"]{0,}=[" +"]{0,}['"][a-zA-Z0-9" "]+['"]+[;]{0,}
上面的正则表达式将找到所有$vars
以及它们的设置。我使用它来使用Dreamweaver搜索整个目录和站点。以下是我的上述正则表达式中将找到哪种PHP变量的示例。
$var = 'sample';
$var = "sampletext"
$var="sampletext"
$$$var = "sampletext"
$var = "sampletext"
$var= 'sampletext';
$var = 'here is some sample text';
var = 'here is more sample text';
您可以看到上述所有变量都有轻微变化。有些使用双引号,单引号,有些使用分号,有些则没有,也有空格的变体。
所以,我的问题,你能简化我的正则表达式吗?你们都有其他正则表达式用于VET和ANALYIZE任何代码,但特别是PHP会很好。非常感谢您抽出时间阅读并提供帮助。
答案 0 :(得分:3)
问题和回答中的正则表达式都在寻找变量赋值表达式;如果您只是在寻找第一项任务,这将使问题复杂化,并且您更好 - 正如@mario所说 - 使用 PHP_Parser
。
这个正则表达式有很多奇怪的方面。首先是一个奇怪的正则表达式构造的小枚举:
\${1,1}
{1,1}
表示一个和一个之间的时间。这是无用的,可以用\$
替换。
[\w]+
在这里,您只使用一种类型的字符,一个语义上等效的表达式为\w
,但这部分有问题。这个document表示变量的名称只能以字母或下划线开头。其次是字母,下划线和数字。 \w
仅表示最后一个类别。因此,$0
之类的表达式将匹配。但是文档显示了如何指定变量名称:
[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
[" +"]{0,}
在这里,我并不完全确定你的目标是什么;您似乎为正则表达式提供零或更多引号重复("
),空格()和加号(
+
)的选择。如果您想要零个或多个间距字符,则可以使用\s*
。分配后的部分也是如此。
=
这里假设您只能使用赋值声明变量。事实并非如此:PHP允许使用默认值,例如写$var += 3;
。在这种情况下,$var
将" 初始化"使用3
,因为默认值为0
。我同意这是糟糕的设计。您可以选择使用([+-*/%.&|^]|<<|>>)?
。
再次间隔;见第4号。
['"][a-zA-Z0-9" "]+['"]+[;]{0,}
。
表达式,很难解析赋值运算符旁边的PHP表达式。它可以是常量,如数字,但这些可以是变量,字符串,函数调用,...函数调用甚至可以在f(1,2,g(3,'a'))
等级联。通过标准正则表达式,这些调用甚至无法正确处理:它是一个常规语言抽取引理的结果。然而,PHP允许平衡括号扩展,所以理论上它可以完成。在这种情况下,你需要深入研究PHP的上下文免费语法,使其变得更加困难。
您还要说明一些表达式不以分号结尾。然而,php -a
交互式shell似乎并不喜欢这个想法:
$ php -a
php > $var
php > echo $var;
PHP Parse error: syntax error, unexpected 'echo' (T_ECHO) in php shell code on line 2
您可以使用分号作为查找表达式何时终止的方法。例如:
.*?;
这会有效,但是有一个问题:分号也可以放在字符串中。在这种情况下,需要忽略分号。您可以使用正则表达式替换点.
:
([^"']|(["'][^"]*["']))*?
但这又会导致问题,因为引用可以转义(如"\""
);在这种情况下,您不希望正则表达式将第二个"
解释为字符串的结尾。你可以通过使正则表达式更复杂来解决这个问题:
([^"']|(["']([^"\\]|\\.)*["']))*?
因此,正则表达式可以读取:
\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\s*([+-*/%.&|^]|<<|>>)?=\s*([^"']|(["']([^"\\]|\\.)*["']))*?;
如前所述要求表达式以分号结尾。字符串环境中的分号将被忽略。