高级正则表达式替换.检查是否在<脚本>标记中


Advanced regex replacement. Check if in <script> tag

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

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';
}

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

如评论中所述:

如果你的 php 函数总是有一个可见性修饰符,比如public你可以这样做:

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

否则,您可以先剥离脚本部分。像这样:

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

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

您的原始正则表达式不是很好,因为它匹配

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

也许如果你让它更健壮,它会解决你的问题:

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

这将确保它是 99% 的情况的函数声明。仍然有一些不寻常的情况,你可以愚弄它。

再多的正则表达式也无法实现像样的防故障解决方案。

正确的方法是使用 php 标记器。

<?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";');