2012-01-13 64 views
3

將此正則表達式簡化爲更簡潔的格式有更好的方法,但我似乎無法正確實現字符組以供重用。如何更好地完成這場比賽的任何其他建議將是值得肯定的。在C#正則表達式中正確使用字符組

擬比賽:

<Formatting Type="B">any text</Formatting> 

這可能其他格式化標籤內嵌套像這樣

<Formatting Type="B"><Formatting Type="I">any text</Formatting>any text</Formatting> 

下面的正則表達式的伎倆,但似乎更復雜比它應該是,因爲我使用本節重複我自己三次

最終目標是用標準HTML標記替換<Formatting的所有實例<B> <I> <U>

[\040\w!\?\:\.]* 

總體正則表達式如下

<Formatting Type="[BIU]{1}">([\040\w!\?\:\.]*(<[BIU]>)*[\040\w!\?\:\.]*(</[BIU]>)*[\040\w!\?\:\.]*)*</Formatting> 

回答

1

我認爲你會發現這很困難,特別是由於這樣的事實,格式化標籤可以相互嵌套。

你可能想避免被驅使到瘋狂,如apparently this fellow StackOverflow user was

This answer表明它可以通過使用「平衡匹配」來完成。

嘗試使用XML技術來完成此操作(可能是XSLT)而不是正則表達式可能會更好。

2

我想這是你想要的:

<Formatting Type="([BIU])">([ \w!?:.]*(?:</?[BIU]>[ \w!?:.]*)*)</Formatting> 

有沒有必要有用於打開和關閉HTML標記獨立生產,那就必須<B><I><U>標籤來區分了。重要的是,在匹配開頭<Formatting>標籤後,在結束</Formatting>標籤之前,您不會消耗任何更多開標籤。如果原始標籤嵌套正確,HTML標籤也會如此。

我假設只有三種格式,並且在文本中不會有任何其他尖括號或標籤類的東西。既然如此,你不需要對正則表達式做如此限制。

text = Regex.Replace(text, 
    @"<Formatting Type=""([BIU])"">([^<]*(?:</?[BIU]>[^<]*)*)</Formatting>", 
    @"<$1>$2</$1>"); 

當然,您需要在文本上多次傳遞以確保您已替換所有標記。鑑於您的示例文本:

<Formatting Type="B"><Formatting Type="I">any text</Formatting>any text</Formatting> 

...第一遍後,將改爲:

<Formatting Type="B"><I>any text</I>any text</Formatting> 

...和第二遍後:

<B><I>any text</I>any text</B>