0

谁能帮我解决正则表达式问题。我正在制作一个脚本来遍历我所有的 .php 文件并将所有字符串传递给某个函数。我需要匹配这种情况:

/* Double quotes */
function("some string"); // Match: some string
function("some \"string\""); // Match: some "string"
function("some 'string'"); // Match: some 'string'

/* Single quotes */
function('some string'); // Match: some string
function('some \'string\''); // Match: some 'string'
function('some "string"'); // Match: some "string"

函数也可以接受字符串后面的参数,所以也需要匹配这种情况:

/* Additional parameters */
function("some string", "param"); // Match: some string
function("some string", $param); // Match: some string

所以本质上,param 可以是字符串(带引号或双引号)或不带引号的变量。我只需要从函数的第一个参数获取字符串,无论第二个参数是否存在或以任何方式被引用......

提前致谢...

4

4 回答 4

0

而不是使用正则表达式(你自己),你可以使用一个 php 解析器,它给你某种AST,例如在生成 PHP 源文件的 AST 中接受的答案

<?php
require 'path/to/PHP-Parser-master/lib//bootstrap.php';

class MyNodeVisitor extends PHPParser_NodeVisitorAbstract
{
    public function beforeTraverse(array $nodes) {}
    public function enterNode(PHPParser_Node $node) { }
    public function leaveNode(PHPParser_Node $node) { 
        if ($node instanceof PHPParser_Node_Expr_FuncCall) {
            if ( 'foo'===(string)$node->name ) {
                foreach( $node->args as $arg ) {
                    echo $arg->value->value, "\n";
                }
            }

        }
    }
    public function afterTraverse(array $nodes) {}
}


$parser = new PHPParser_Parser(new PHPParser_Lexer);
$nv = new MyNodeVisitor;
$traverser = new PHPParser_NodeTraverser;
$traverser->addVisitor($nv);


try {
    $stmts = $parser->parse( data() );
        $stmts = $traverser->traverse($stmts);

} catch (PHPParser_Error $e) {
    echo 'Parse Error: ', $e->getMessage();
}





function data() {
    return <<< eot
<?php   
/* Double quotes */
foo("some string"); // Match: some string
foo("some \"string\""); // Match: some "string"
foo("some 'string'"); // Match: some 'string'

/* Single quotes */
foo('some string'); // Match: some string
foo('some \'string\''); // Match: some 'string'
foo('some "string"'); // Match: some "string"   
eot;
}

印刷

some string
some "string"
some 'string'
some string
some 'string'
some "string"
于 2012-12-21T14:17:09.597 回答
0

这里我写了一个脚本sed。将其保存在文件中file.sed

bs
:gf
s:,.*$::
s:^.::
s;.$;;
s:[\]\(["']\):\1:g
p;d
:s
/.*(\([^)]*\).*/ s::\1:
tgf
d

接下来,运行它sed -f file.sed FILE.py

for x in `find -name \*.py`; do sed -f file.sed $x; done

编辑:

可以用 oneliner sed 命令替换脚本,但是调用它以便调试它的功能非常清楚。

于 2012-12-21T14:27:55.863 回答
0

这是一个可以帮助您入门的快速草图:

while (readline) {
    my ($matched) = m{
        \b function \s* \( \s*
        (
            " (?: [^"\\] | \\ .)* "
        |
            ' (?: [^'\\] | \\ .)* '
        )
    }sx or next;
    my $value = php_unescape $matched; # XXX: write me
    print $value, "\n";
}
于 2012-12-21T13:56:10.580 回答
0

您的特定示例已成功处理...

preg_match_all('#\\(\\s*("((\\\\.|[^"])+)"|\'((\\\\.|[^\'])+)\'),?#s', $test, $matches);

这是ideone 演示

说明:我们尝试匹配左括号(谢天谢地,它是 PHP;在 Ruby 中要困难得多),然后是任意数量的空白字符,然后是...

  • 任何一个"(\\.|[^"])+"
  • 或者'(\\.|[^'])+'

... 后跟可选逗号。

每个序列都涵盖“特殊字符”(用斜杠转义)和“普通字符”(与分隔符不同)。

于 2012-12-21T14:02:57.530 回答