2011-05-14 63 views
7

我需要匹配整個以下語句:正則表達式嵌入{{匹配

{{CalendarCustom|year={{{year|{{#time:Y}}}}}|month=08|float=right}} 

基本上只要有{需要有相應的}然而與許多嵌入式{ }是原始標籤內。因此,例如{{match}}{{ma{{tch}}}}{{m{{a{{t}}c}}h}}

我現在有這個權利:

(\{\{.+?(:?\}\}[^\{]+?\}\})) 

這完全不是那麼回事。

+0

究竟是你想擺脫的字符串是什麼? – Oded 2011-05-14 15:00:58

+0

我只是想匹配整個陳述,所以我可以刪除它。就像周圍有其他文字一樣,我想匹配{}括號內的任何內容並將其刪除。 – thirsty93 2011-05-14 15:02:53

+2

一般而言,正則表達式不是匹配括號的正確工具,請參閱。例如[這裏](http://stackoverflow.com/q/546433/577423)。 – Howard 2011-05-14 15:06:38

回答

15

的.NET正則表達式引擎允許遞歸匹配:

result = Regex.Match(subject, 
    @"\{     # opening { 
     (?>    # now match... 
      [^{}]+   # any characters except braces 
     |     # or 
      \{ (?<DEPTH>) # a {, increasing the depth counter 
     |     # or 
      \} (?<-DEPTH>) # a }, decreasing the depth counter 
     )*     # any number of times 
     (?(DEPTH)(?!))  # until the depth counter is zero again 
     \}     # then match the closing }", 
    RegexOptions.IgnorePatternWhitespace).Value; 
+0

感謝您指出這一點。今天學到了一些東西......你有鏈接文件''? – Oded 2011-05-14 15:17:59

+0

@Oded:'DEPTH'是一個任意名稱 - 它只是一個空的命名捕獲組(')',它在.NET中計數匹配的數量; '(?')是一樣的,只是減少櫃檯。而'(?(ID)(?!))'只有在'id'計數器爲零時才匹配。這在Friedl的「掌握正則表達式」的第436頁中有記錄。 – 2011-05-14 15:23:10

+0

那本書在我的書架上,正在等待閱讀... – Oded 2011-05-14 15:24:03

4

我建議爲此寫一個簡單的解析器/標記器。

基本上,你遍歷所有的字符,並開始計數{}實例 - 增加了{和遞減爲}。記錄每個第一個{的索引和每個最後的}的索引,並且您將擁有嵌入式表達式的索引。

在這一點上,您可以使用substring來獲得這些並從原始字符串中刪除/替換它們。

請參閱this爲什麼RegEx不適合的問題和答案。

+0

我第二個這樣做。我曾經見過一家我曾經工作過的公司,通過正則表達式進行解析,似乎它會變得更容易。這是一個很大的學習曲線,但從長遠來看這將是值得的。查看ANTLR的出發點...... – 2011-05-14 15:20:10

+0

下面是使用ANTLR解析和評估表達式的一個非常簡單的示例。注意定義有效的「標記」是多麼簡單,然後撒入內聯Java源代碼(它也適用於c#),然後ANTLR完成剩下的工作。 http://www.antlr.org/wiki/display/ANTLR3/Expression+evaluator – 2011-05-14 15:26:23

+0

我正在做一些在xbox上運行的東西,所以不允許非託管代碼。 – thirsty93 2011-05-14 15:58:24