【问题标题】:Advanced regex replacement. Check if in <script> tag高级正则表达式替换。检查是否在 <script> 标签中
【发布时间】:2012-05-25 09:04:30
【问题描述】:

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

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

如何在我的正则表达式中做到这一点?

【问题讨论】:

  • 太复杂了。不能只用一个preg_match_all()
  • 先提取所有的js数据,然后运行你的脚本,然后再次追加你的脚本数据。
  • @RohitKumarChoudhary 这实际上也是一个不错的解决方案。你能给出一个真正的答案吗?如果没有其他人提出更好的建议,我可能会接受。
  • @Vivendi 根据您问题的复杂性,很难在短时间内给出正确的解决方案。我也必须对此进行研究:)
  • 如果你只是将代码注入到 javascript 中,更恰当的选择就是挂钩你正在修改的函数。

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


【解决方案1】:

如 cmets 中所述:

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

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

否则,您可以先剥离脚本部分。 比如:

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

【讨论】:

    【解决方案2】:

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

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

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

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

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

    这将确保它在 99% 的情况下都是函数声明。仍然有一些不寻常的情况可以欺骗它。

    【讨论】:

      【解决方案3】:

      再多的正则表达式都无法实现一个不错的防故障解决方案。

      正确的做法是使用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";');
      

      【讨论】:

      • 请注意,这仅适用于有效的 php/html 输入(即:代码必须以 或
      猜你喜欢
      • 2015-11-07
      • 2011-12-21
      • 1970-01-01
      • 2012-04-27
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      • 1970-01-01
      • 2021-02-19
      相关资源
      最近更新 更多