2014-11-14 98 views
1

我正在寫一個Python程序,用於使用正則表達式在C++程序中搜索註釋。 我寫了下面的代碼:用正則表達式在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; 
} 

回答

1

您沒有使用好爲了做到這一點多行註釋裏面,因爲內部註釋可以包括。所以你需要用多行註釋開始你的模式。例如:

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

注意,如果你有長多行註釋可以改善這種情況(這句法是原子團特性的仿真未被re模塊支持)

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

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

所以,如果你想避免這種情況下,例如,如果你想更換,你需要字符串之前捕獲並在替換字符串中使用反向引用,就像這樣:

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

更換:$1

+0

在我的情況下,這些陷阱是不可能的:) – Dheerendra 2014-11-14 21:56:39

+0

@Dheerendra:所以你只需要簡單的答案。 – 2014-11-14 21:57:42

0

使用組(0) 在 'TXT' 文件中的內容就是你們的榜樣:

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 
+0

我不想讓換行符 – Dheerendra 2014-11-14 22:08:17

+0

爲您更好地理解,group(1)表示第一個加括號的子組。在你的情況是「//」,它不能找到你的「/ * ... * /」情況 – 2014-11-14 22:08:25

+0

你可以在打印前修剪「\ n」 – 2014-11-14 22:09:06

0

不幸的是,你必須在同一時間解析報價和非註釋,因爲
部分評論語法可嵌入其中。

這是一個古老的Perl正則表達式,可以做到這一點。一場比賽的興趣是捕獲組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) 
0

添加另一個答案。

(注 - 您有沒有涉及到的交替順序註釋子表達式
問題)

你們是簡化正則表達式版本,以獲得C++評論
,如果你不想要完整版本,我們可以看看
爲什麼你有問題。

首先你的正則表達式是差不多是正確的。有一個問題
/* ... */評論的子表達式。內容必須爲
非貪心

除此之外,它的工作原理應該如此。
但是你應該仔細觀察捕獲組。
在您的代碼中,您只在每場比賽中打印組1,這是// ...
評論。您可以檢查組1和3中的匹配,或者
只打印出組0(整個比賽)。

此外,您不需要懶惰量詞?第2組,並
換行符\n下面應該在那裏。
而且,考慮讓所有捕獲組不捕獲(?: ..)

因此,請在// ...子表達式中刪除?量詞和\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