高级正则表达式替换。检查是否在<script>标记</script>中

时间:2012-05-25 09:04:31

标签: php regex preg-match preg-match-all

我有一个简单的正则表达式,它检查整个字符串的函数声明。所以在这段代码中:

public function Test($name)
{
    echo 'In test';
}

它将找到第一部分:

function Test($name)
{

它用一个自定义的部分取而代之:

function Test($name)
{
    echo 'New piece';

最终使我的代码看起来像这样:

public function Test($name)
{
    echo 'New piece';
    echo 'In test';
}

这一切都适用于这个正则表达式:

preg_match_all ( '/function(.*?)\{/s', $source, $matches )

问题是,当正则表达式看到脚本标记时,我想忽略所有内容。所以在这种情况下,这个来源:

public function Test($name) //<--- Match found!
{
    echo 'In test';
}

<script type="text/javascript"> //<--- Script tag found, dont do any matches!
$(function() {
    function Test()
    {
        var bla = "In js";
    }
});
</script> //<--- Closed tag, start searching for matches again.

public function Test($name) //<--- Match found!
{
    echo 'In test';
}

我如何在我的正则表达式中执行此操作?

3 个答案:

答案 0 :(得分:1)

如评论中所述:

如果您的php函数始终具有public之类的可见性修饰符,则可以执行以下操作:

(?:public|protected|private)\s+function\s+\w+\(.*?\)\s*\{

否则,您可以先删除脚本部分。 类似的东西:

$text = preg_replace('/<script(?:(?!<\/script>).)*<\/script>/s','',$text);

答案 1 :(得分:1)

我不懂python,但我知道正则表达式:

你的原始正则表达不太好,因为它匹配

// This is a functional comment { isn't it? }
             ^^^^^^^^...........^

也许如果你让它更强大,它将解决你的问题:

  
    

^\s*(public|protected|private)\s+function\s+\(.*?\).*?{

  

这将确保它是99%案例的功能声明。还有一些不寻常的情况你可以欺骗它。

答案 2 :(得分:0)

没有多少正则表达式可以实现一个不错的防故障解决方案。

执行此操作的正确方法是使用php tokenizer

<?php

$code = <<<END
<?php 
public function Test(\$name) //<--- Match found!
{
    echo 'In test';
}
?>
<script type="text/javascript"> //<--- Script tag found, dont do any matches!
$(function() {
    function Test()
    {
        var bla = "In js";
    }
});
</script> //<--- Closed tag, start searching for matches again.
<? 
public function Bla(\$name) //<--- Match found!
{
    echo 'In test';
}
END;


function injectCodeAtFunctionsStart ($originalCode, $code)
{
    $tokens = token_get_all ($originalCode);

    $newTokenTree = '';

    // iterate tokens
    for ($i = 0, $total = count($tokens); $i < $total; $i++) 
    {
        $node = $tokens[$i];
        $newTokenTree[] = $node;

        if (is_array ($node)) 
        {
            // function start
            if ($node[0] == T_FUNCTION) 
            {
                // walk to first brace
                while ($tokens[$i] !== '{') {
                    $newTokenTree[] = $tokens[$i];
                    $i++;
                }
                $i++;

                // keep space
                $space = $tokens[$i];
                $newTokenTree[] = $space;

                // add new piece
                $newTokenTree[] = $code;
                $newTokenTree[] = $space;
            }
        }
    }

    // rebuild code from tokens    
    $content = '';
    foreach ($newTokenTree as $node) {
        $content .= is_scalar ($node) ? $node : $node[1];
    }

    return $content;
}


echo injectCodeAtFunctionsStart ($code, 'echo "new piece";');