2010-08-13 60 views
6

我想驗證腳本引擎的一些C#源代碼。我想確保只有System.Math類成員可能被引用。我正在嘗試創建一個正則表達式,該正則表達式將匹配一個點,後跟一個大寫字母,後跟任意數量的單詞字符,以不以System.Math開頭的單詞邊界結束。正則表達式頭痛

我開始用這樣的:

(?<!Math)\.[A-Z]+[\w]* 

工作正常進行:

return Math.Max(466.89/83.449 * 5.5); // won’t flag this 
return Xath.Max(466.89/83.449 * 5.5); // will flag this 

它正確地匹配。最大時,它不是由數學之前。但是,現在我試圖擴展正則表達式來包含System,我無法使其正常工作。

我已經試過正則表達式的這些排列多:

((?<!System\.Math)\.[A-Z]+[\w]*) 
((?<!(?<!System)\.Math)\.[A-Z]+[\w]*) 
((?<!System)\.(?<!Math)\.[A-Z]+[\w]*) 
((?<!System)|(?<!Math)\.[A-Z]+[\w]*) 
((?<!System\.Math)|(?<!Math)\.[A-Z]+[\w]*) 

使用這些語句:

return System.Math.Max(466.89/83.449 * 5.5); 
return System.Xath.Max(466.89/83.449 * 5.5); 
return Xystem.Math.Max(466.89/83.449 * 5.5); 

我已經試過了我能想到的一切,但它要麼始終匹配第二個元素(上面的.Math或.Xath)或它不匹配任何。

如果有人會憐憫我,並指出我做錯了什麼,我會大大appit它。

由於提前, 韋爾頓

+0

我以爲肯定我有一個解決方案,但現在我重新發現了所有列出的表達式,並破壞了我的大腦。確實非常棘手! – 2010-08-13 00:35:53

+0

'Math.'會獨自出現,還是總是以'System.'開頭? – 2010-08-13 00:36:17

+4

您是否考慮過使用編譯器(CSharpCodeProvider),然後使用CodeDom對象圖來掃描除System.Math之外的其他引用?這將是防彈,更可讀,更靈活。 – 2010-08-13 00:39:10

回答

2

訣竅是確保你永遠不會在開始時在任何地方開始匹配成員名稱。然後,使用lookahead來簡單的問題來確定您正在查看的內容是否以System.Math.開頭。試試這個正則表達式:

(?<![\w.])(?!(?:System\.)?Math\.)(?:[A-Z]\w*\.)+[A-Z]\w*\b 

的回顧後保證比賽不以字(\w)或合格的成員名稱(.)的中間位置的中間開始。現在,如果前瞻失敗,它不能跳到下一個組件的開頭(例如System.Math.中的Math.),然後重試。這是全部或沒有。

但是,如果此前沒有System.,則此將與匹配Math.Max。你真的需要這個,還是僅僅是爲全名開發一個正則表達式的中間步驟?

編輯:我繼續前進,並使System.部分可選。

+0

這也行! – dawg 2010-08-13 01:28:08

2

如果你只是在尋找你的例子說明,此正則表達式將做到這一點。

^[\w\s]*?[A-Z]\w+\.[A-Z]\w+\.(?<!System\.Math\.)

它只要比System.Math.XXX這是其他所有呼叫匹配爲:a)有在呼叫的兩個.,b)該呼叫是在一行上。

return System.Math.Max(466.89/83.449 * 5.5); // no match 
return System.Xath.Max(466.89/83.449 * 5.5); // match 
return Xystem.Math.Max(466.89/83.449 * 5.5); // match 
System.Math.Max(466.89/83.449 * 5.5); // no match 
System.Xath.Max(466.89/83.449 * 5.5); // match 
Xystem.Math.Max(466.89/83.449 * 5.5); // match 
return System.Math.Max(466.89/83.449 * 5.5); // no match 
return System.Xath.Max(466.89/83.449 * 5.5); // match 
return Xystem.Math.Max(466.89/83.449 * 5.5); // match 
Math.Max(466.89/83.449 * 5.5);    // no match - only one '.' 
System.Max.Math(466.89/83.449 * 5.5);  // match 

雖然我同意評論意見,任何正則表達式都非常脆弱,只應該被認爲是一種文本編輯器類型的幫助。如果你希望它是防彈的,你需要一個解析器。

+0

返回時不起作用Xath.Max(466.89/83.449 * 5.5); – 2010-08-13 01:42:59

+0

@Richard:OP狀態他想最終匹配嗎?我的理解是,'Math.Max(466.89/83.449 * 5.5);''和'Xath.Max(466.89/83.449 * 5.5);'其中正則表達式的中間發展... – dawg 2010-08-13 01:48:51

+0

不確定...如果他說沒關係,那你就明白了。 – 2010-08-13 02:07:04