【问题标题】:preg_replace on certain conditionspreg_replace 在某些条件下
【发布时间】:2012-01-31 12:06:23
【问题描述】:

我想 preg_replace 一些文本,但前提是它没有被评论。这是给定文本的示例:

// delete_me('First');
delete_me('Second');
/* delete_me('Third'); */
delete_me('Fourth'); // Some comment behind a command.
/* Tiny bit of comment */ delete_me('Fifth');

现在在这个例子中,我只想替换第二、第四和第五行。我想用新参数替换参数。所有文本都在一个大字符串中,由换行符分隔。

我确实有一些 preg_replaces 可以删除评论部分,但由于我不想删除它们,它没有多大用处,但也许它可以帮助某人帮助我。

$text = preg_replace("/\/\/(.*)/", $replace, $text);
$text = preg_replace('!/\*(.*)\*/!s', $replace, $text);

谁能帮我替换没有 PHP 注释的行上的给定参数?谢谢!

【问题讨论】:

  • 我认为这对于正则表达式是不可能的。它与 HTML 和 Regex 相同。您不能简单地匹配注释,因为它们可能在一个字符串中,并且您不能匹配这些字符串,因为它们可能在 cmets 中。你需要的是 PHP Tokenizer。
  • 这不是真的。您可以在合理范围内匹配字符串,请参阅下面的评论。
  • @TimWolla 但您可以将正则表达式用作简单的分词器...
  • delete_me('is this /* commented? */');

标签: php regex preg-replace


【解决方案1】:

首先将文本分成评论和非评论的块,然后只改变非评论的部分,最后将它们粘合在一起:

$in = "// delete_me('First');
delete_me('Second');
/* delete_me('Third'); */
delete_me('Fourth'); // Some comment behind a command.
/* Tiny bit of comment */ delete_me('Fifth');\n";

$split = preg_split("#(//[^\n]*\n|/\\*.*?\\*/)#s",$in,-1,PREG_SPLIT_DELIM_CAPTURE);

foreach ( $split as $i=>$chunk )
{
    if ( $i%2==0 )
    {
        $split[$i] = preg_replace("/'.*?'/","'newparam'",$chunk);
    }
}

echo implode($split);

输出:

// delete_me('First');
delete_me('newparam');
/* delete_me('Third'); */
delete_me('newparam'); // Some comment behind a command.
/* Tiny bit of comment */ delete_me('newparam');

这里的诀窍是提供给preg_split 的模式与注释块相匹配,因此您会得到一组偶数/奇数代码/注释。

警告 当您将/* 放在字符串文字中时,这当然会中断。

【讨论】:

  • 工作就像一个魅力,一个好的理论。还没想到呢!非常感谢!
  • 不适用于// foo('bar')// comment 后面不必跟换行符。当然,像foo('b//r') 这样引用的东西也会有问题。
  • 确实不适用于参数内的注释。但这不是最大的问题。
  • @Qtax:你的意思是当该行是文件的最后一行,末尾没有换行符?现在 that 是一个极端情况。
【解决方案2】:
preg_replace("[^\/\*]+", $replace, $text);

应该有效

【讨论】:

  • 如果你有第 1 行怎么办:“/* woohoo 我也评论了下一行!”第 2 行:“foo (bar ()) */”
  • 不幸的是,这会提示错误:警告:preg_replace(): Unknown modifier '\' - 但是上面的答案有效。无论如何,感谢您的努力。 :)
  • 您想忘记每行评论吗?
猜你喜欢
  • 1970-01-01
  • 2022-12-17
  • 1970-01-01
  • 2012-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多