使用preg_replace删除C注释

时间:2014-03-07 19:50:53

标签: php regex string

我需要擦除$ string中包含来自某个C文件的数据的所有注释。 我需要替换的东西是这样的:

something before that shouldnt be replaced
/*
*  some text in between with / or * on many lines
*/
something after that shouldnt be replaced

,结果应如下所示:

something before that shouldnt be replaced
something after that shouldnt be replaced

我尝试了许多正则表达式,但都没有按照我需要的方式工作。 以下是一些最新的:

$string = preg_replace("/\/\*(.*?)\*\//u", "", $string);

$string = preg_replace("/\/\*[^\*\/]*\*\//u", "", $string);

注意:文本是UTF-8,字符串可以包含多字节字符。

4 个答案:

答案 0 :(得分:2)

您还需要添加s修饰符,以告诉正则表达式.*应包含换行符。我一直认为s表示“将输入文字视为s ingle line”

所以这样的事情应该有效:

$string = preg_replace("/\\/\\*(.*?)\\*\\//us", "", $string);

示例:http://codepad.viper-7.com/XVo9Tp

编辑:正如Brandin建议的那样,为正则表达式添加了额外的转义斜杠,因为他是对的。

答案 1 :(得分:1)

我不认为正则表达式在这里很合适。怎么写一个非常小的解析来删除它?我很长时间没做PHP编码。所以,我会试着给你一个想法(简单的算法)我没有测试过这个,只是你得到了这个想法,就像我说的那样:

buf = new String() // hold the source code without comments
pos = 0
while(string[pos] != EOF) {
  if(string[pos] == '/') {
    pos++;
    while(string[pos] != EOF)
    {
      if(string[pos] == '*' && string[pos + 1] == '/') {
       pos++;
       break;
      }
      pos++;
    }
  }
  buf[buf_index++] = string[pos++];
}

其中:

string是C源代码

buf动态分配的字符串,根据需要进行扩展

答案 2 :(得分:0)

试试这个:

$string = preg_replace("#\/\*\n?(.*)\*\/\n?#ms", "", $string);

使用作为正则表达式边界;将 u 修饰符更改为正确的修饰符: m(PCRE_MULTILINE) s(PCRE_DOTALL)

参考:http://php.net/manual/en/reference.pcre.pattern.modifiers.php

重要的是要注意我的正则表达式找不到多个“注释块”...使用“点匹配全部”通常不是一个好主意。

答案 3 :(得分:0)

如果没有最终编写完整的C解析器,很难完成这项工作。

考虑以下内容,例如:

// Not using /*-style comment here.
// This line has an odd number of " characters.
while (1) {
    printf("Wheee!
        (*\/*)
         \\// - I'm an ant!
    ");
    /* This is a multiline comment with a // in, and
    // an odd number of " characters. */
}

因此,从上面可以看出,我们的问题包括:

  • 双引号内应忽略多行引号序列。除非这些双引号是评论的一部分。
  • 单行注释序列可以包含在双引号字符串和多行字符串中。

这是解决其中一些问题的一种可能性,但远非完美。

// Remove "-strings, //-comments and /*block-comments*/, then restore "-strings.
// Based on regex by mauke of Efnet's #regex.
$file = preg_replace('{("[^"]*")|//[^\n]*|(/\*.*?\*/)}s', '\1', $file);