用regex搜索C ++中的基本注释

时间:2014-11-14 21:47:28

标签: python regex

我正在编写一个Python程序,用于使用正则表达式在c ++程序中搜索注释。 我写了以下代码:

import re
regex = re.compile(r'(\/\/(.*?))\n|(\/\*(.|\n)*\*\/)')
comments = []
text = ""
while True:
    try:
        x= raw_input()
        text = text + "\n"+ x
    except EOFError:
        break
z = regex.finditer(text)
for match in z:
    print match.group(1)

此代码应检测//I'm comment/*blah blah blah blah blah*/类型的评论 我得到了以下输出:

// my  program in C++
None
//use cout

我没想到。我的想法是match.group(1)应该捕获(\/\*(.|\n)*\*\/)的第一个括号,但事实并非如此。 我正在测试的c ++程序是:

// my  program in C++

#include <iostream>
/** I love c++
    This is awesome **/
using namespace std;

int main ()
{
  cout << "Hello World"; //use cout
  return 0;
}

4 个答案:

答案 0 :(得分:1)

您没有使用正确的顺序来执行此操作,因为内联注释可以包含在多行注释中。因此,您需要使用多行注释开始您的模式。例如:

/\*[\s\S]*?\*/|//.*

请注意,如果您有长多行注释,则可以改进此模式(此语法是re模块不支持的原子组功能的模拟)

/\*(?:(?=([^*]+|\*(?!/))\1)*\*/|//.*

但请注意,还有其他陷阱,例如包含/*...*///.....的字符串。

因此,如果您想避免这些情况,例如,如果您想要进行替换,则需要在字符串之前捕获并在替换字符串中使用反向引用,如下所示:

(pattern for strings)|/\*[\s\S]*?\*/|//.*

替换:$1

答案 1 :(得分:0)

使用组(0) &ttxt&#39;中的内容文件就是你的例子:

import re
regex = re.compile(r'(\/\/(.*?))\n|(\/\*(.|\n)*\*\/)')
comments = []
text = ""
for line in open('txt').readlines():
    text = text + line
z = regex.finditer(text)
for match in z:
    print match.group(0).replace("\n","")

我的输出为:

// my  program in C++
/** I love c++        This is awesome **/
//use cout

帮助人们理解:

import re
regex = re.compile(r'((\/\/(.*?))\n|(\/\*(.|\n)*\*\/))')
comments = []
text = ""
for line in open('txt').readlines():
    text = text + line
z = regex.finditer(text)
for match in z:
    print match.group(1)

会输出:

// my  program in C++

/** I love c++
    This is awesome **/
//use cout

答案 2 :(得分:0)

不幸的是,你必须同时解析引号和非注释因为
部分注释语法可以嵌入其中。

这是一个老式的Perl正则表达式。匹配的兴趣是Capture group 1
包含评论。所以使用全局搜索while循环。检查第1组匹配。

    # (/\*[^*]*\*+(?:[^/*][^*]*\*+)*/|//(?:[^\\]|\\\n?)*?\n)|("(?:\\[\S\s]|[^"\\])*"|'(?:\\[\S\s]|[^'\\])*'|[\S\s][^/"'\\]*)


    (                                # (1 start), Comments 
         /\*                              # Start /* .. */ comment
         [^*]* \*+
         (?: [^/*] [^*]* \*+ )*
         /                                # End /* .. */ comment
      |  
         //                               # Start // comment
         (?: [^\\] | \\ \n? )*?           # Possible line-continuation
         \n                               # End // comment
    )                                # (1 end)
 |  
    (                                # (2 start), Non - comments 
         "
         (?: \\ [\S\s] | [^"\\] )*        # Double quoted text
         "
      |  '
         (?: \\ [\S\s] | [^'\\] )*        # Single quoted text
         ' 
      |  [\S\s]                           # Any other char
         [^/"'\\]*                        # Chars which doesn't start a comment, string, escape,
                                          # or line continuation (escape + newline)
    )                                # (2 end)

答案 3 :(得分:0)

添加另一个答案。

(注意 - 您遇到的问题与更改顺序无关 注释子表达式。)

你的是获得C ++评论的简化正则表达式版本 如果你不想要完整的版本,我们可以看一看 你为什么遇到问题。

首先,你的正则表达式几乎正确。有一个问题 使用/* ... */注释的子表达式。必须制作内容 非贪婪

除此之外,它的工作方式应该如此 但你应该仔细看一下捕捉组 在您的代码中,您只在每场比赛中打印第1组,即// ...
评论。你可以检查第1组和第3组的匹配,或者 只打印出0组(整场比赛)。

此外,您不需要第2组中的延迟量词?和 它下方的换行符\n NOT 在那里 并且,考虑使所有捕获组不捕获(?: .. )

因此,请移除?子表达式中的\n量词和// ...
并在?子表达式中添加/* ... */量词。

这是您的原始正则表格格式 - (使用 RegexFormat 5 和自动评论)

    # raw regex:   (//(.*?))\n|(/\*(.|\n)*\*/)

    (                    # (1 start)
         //
         ( .*? )              # (2)
    )                    # (1 end)
    \n 
 |  
    (                    # (3 start)
         /\*
         ( . | \n )*          # (4)
         \*/
    )                    # (3 end)

这里没有捕获组和2个次要量词变化。

    # raw regex:   //(?:.*)|/\*(?:.|\n)*?\*/

    //
    (?: .* )
 |  
    /\*
    (?: . | \n )*?
    \*/

输出

 **  Grp 0 -  ( pos 0 , len 21 ) 
// my  program in C++  

---------------------------

 **  Grp 0 -  ( pos 43 , len 38 ) 
/** I love c++
    This is awesome **/  

---------------------------

 **  Grp 0 -  ( pos 143 , len 10 ) 
//use cout