2012-11-01 41 views
0

我試圖編寫一個正則表達式來搜索/ if/while關鍵字作爲從C++源代碼文件中讀取的字符串,但不包括任何包含它們的字詞:TCL:正則表達式來查找是否在字符串中爲

WhatifYes() 
Whatfor() 
Waitforwhile() 

我寫我的正則表達式如下圖所示:

if { [ regexp {(for|while|if)(\s+)(\()} $lineValue ] } { 

但它不是拿起樣病例:

while((int x = 0) > 0); 
while((int x = 0) > 0) 
for(int y =0 ; ;) 
for(int y =0 ; ;); 
if((int x = 9) > 0) 
if((int x = 9) > 0); 

起初我還以爲因爲我的正則表達式是誣陷,是這樣的:

if/for/while \s+ (#space or multiple spaces 

但我試過,包括在上面的例子中空格:

while ((int x = 0) > 0); 
while ((int x = 0) > 0) 
if ((int x = 9) > 0) 
if ((int x = 9) > 0); 

不過正則表達式是行不通的 - 請讓我知道什麼是正則表達式我應該用它來捕捉它們?

+1

,而假若/時/對於總是有一個空間或在他們面前行的開始?似乎你應該在你的正則表達式中有一個空間/開始行。然後在它們之後可以是空格或者「(」或者空格/「(」/行結尾,但是總是有/ if/for內部註釋,這可能不能用一個正則表達式來處理 – Scooter

+0

謝謝是我們需要在註釋中排除字符串if/for/while也有可能他們可能從一個新行開始,或者像這樣{do if(x> y){}} – Prakash

+2

如果你真的熱衷於除了註釋中的內容之外,你必須使用完整的解析器,其他的只是變得太複雜了,會有太多的聯鎖規則。(更重要的是,如果你想了解C++,祝你好運!你需要它......) –

回答

4

你的問題的一部分很容易解決,部分是非常困難的。

容易的部分是確保你已經有了一個整體一句話:\m約束逃逸只有一個單詞的開頭匹配,以及\M約束逃逸末相匹配,所以我們可以使用:

# Nothing capturing; you can add that as necessary 
# Ellipsis for the bits I've not talked about yet 
regexp {\m(?:while|if|for)\M\s*...} ... 

非常難的部分是在括號中匹配部分。問題在於,這實際上是一種「語言」(從理論上講),它需要一種不同於正則表達式的解析器來匹配(即,遞歸下降解析器,其具有比用於有限自動機更復雜的狀態模型RE匹配)。更重要的是,在這些表達式中使用()字符是很常見的。最簡單的方法是匹配在行末尾的一個右括號,可能後跟一個分號,但這絕對不正確。或者,支持有限數量的嵌套parens也是可能的。

# Match a few levels... 
regexp {\m(?:while|if|for)\M\s*\((?:[^()]|\((?:[^()]|\([^()]*\))*\))*\)} ... 

所以,讓我們打破失意:

 
\m        Word start 
(?:while|if|for)     One of the keywords 
\M        Word end 
\s*        Optional spaces 
\(        Open paren 
    (?:        Either... 
    [^()]       Non-paren... 
    |        Or... 
    \(        Open paren 
     (?:       Either... 
     [^()]       Non-paren... 
     |        Or... 
     \(       Open paren 
      [^()]*      Non-parens 
     \)       Close paren 
    )*       ... as many of the above as needed 
    \)        Close paren 
)*        ... as many of the above as needed 
\)        Close paren 

如果你看看上面,你會發現一個模式。是的,你可以繼續嵌套做到你想要的深度。 不能做的是讓RE引擎爲你做這個嵌套。

+0

非常感謝描述性的細節。這對我更好地理解正則表達式有很大的幫助。請注意,我試圖使用正則表達式,但無法將其映射到問題中提及的if/for /的示例?我錯過了什麼嗎? – Prakash

+0

謝謝我在我的代碼中發現了問題 - 修復它解決了問題並且完美地工作。 – Prakash

+1

此外,上述代碼不會處理註釋,字符串或字符文字中的不平衡括號。解析很難! –

0

在你的正則表達式中,你正在使用\ s +。這意味着必須至少有一個空格/製表符/換行符。使用\ S *(0或多個空白)和前什麼來添加邏輯:

if { [ regexp {(^|[ \t])(for|while|if)(\s*)(\()} $lineValue ] } { 
相關問題