2010-02-18 62 views
0

如何解決下面的問題?在C#ASP.NET中使用RegEx替換函數

我創建一個簡單的內容管理系統,那裏是一個HTML模板與特定的標記,它表示在內容應該是:

從這個
<html><head></head><body><!-- #Editable "Body1" --><p>etc etc</p><!-- #Editable "Extra" --></body></html> 

獨立,存在這樣看起來數據庫字段內容像這樣的小:

<!-- #BeginEditable "Body1" -->This is Test Text<!-- #EndEditable --><!-- #BeginEditable "Extra" -->This is more test text<!-- #EndEditable --> 

正如您可以猜到,我需要合併兩個,那就是更換

<!-- #Editable "Body1" --> 

有:

This is Test Text 

我已經在這裏開始的代碼。但是我使用正則表達式替換功能,應設在對於/每最底部有問題....

//Html Template 
    string html = "<html><head></head><body><!-- #Editable \"Body1\" --><p>etc etc</p><!-- #Editable \"Extra\" --></body></html>";   

    //Regions that need to be put in the Html Template 
    string regions = "<!-- #BeginEditable \"Body1\" -->This is Test Text<!-- #EndEditable --><!-- #BeginEditable \"Extra\" -->This is more test text<!-- #EndEditable -->"; 

    //Create a Regex to only extract what's between the 'Body' tag 
    Regex oRegex = new Regex("<body.*?>(.*?)</body>", RegexOptions.Multiline); 

    //Get only the 'Body' of the html template 
    string body = oRegex.Match(html).Groups[1].Value.ToString(); 

    // Regex to find sections inside the 'Body' that need replacing with what's in the string 'regions' 
    Regex oRegex1 = new Regex("<!-- #Editable \"(.*?)\"[^>]*>",RegexOptions.Multiline); 
    MatchCollection matches = oRegex1.Matches(body); 

    // Locate section titles i.e. Body1, Extra 
    foreach (Match match in matches) 
    { 
     string title = oRegex1.Match(match.ToString()).Groups[1].ToString(); 
     Regex oRegex2 = new Regex("<!-- #BeginEditable \"" + title + "\"[^>]*>(.*?)<!-- #EndEditable [^>]*>", RegexOptions.Multiline); 
     // 
     // 
     // Replace the 'Body' sections with whats in the 'regions' string cross referencing the titles i.e. Body1, Extra 
     // 
     // 
     // 
    } 

回答

1

性能(或任何其他)不優化,但它的簡單和工程:

var html = "<html><head></head><body><!-- #Editable \"Body1\" --><p>etc etc</p><!-- #Editable \"Extra\" --></body></html>"; 
var regions = "<!-- #BeginEditable \"Body1\" -->This is Test Text<!-- #EndEditable --><!-- #BeginEditable \"Extra\" -->This is more test text<!-- #EndEditable -->"; 
var regionRegex = new Regex(@"<!-- #BeginEditable ""(?<Name>\w+)"" -->(?<Content>.*?)<!-- #EndEditable -->", RegexOptions.Multiline); 
var regionMatches = regionRegex.Matches(regions); 

foreach (Match regionMatch in regionMatches) 
{ 
    var regionName = regionMatch.Groups["Name"].Value; 
    var regionContent = regionMatch.Groups["Content"].Value; 
    html = html.Replace(string.Format(@"<!-- #Editable ""{0}"" -->", regionName), regionContent); 
} 
+0

完美,你讓我感到羞恥! – Stephen 2010-02-18 11:31:28

+1

順便說一下,你應該提升'regionRegex'到私有靜態字段並追加'RegexOptions.Compiled'標誌,並使用'StringBuilder'在循環內進行替換。 – Diadistis 2010-02-18 11:37:40

+0

感謝mill ...現場,我喜歡簡單。 – Stephen 2010-02-18 11:40:45

0

這可能是最好使用Html Agility Pack處理這個給你,然後訴諸正則表達式。它可以將Html解析爲DOM結構中的XML樹,並且使用此包可以更輕鬆地處理此問題。

編輯:

 
string sReg = @"<body.*?>((?<Region>\<\!\-\-\s+\#Editable\s?\\$(?<editable>.+)\\$\s?\-\-\>[^\>]).*?)"; 
string sNewReg = sReg1.Replace('$', '\"');   System.Diagnostics.Debug.WriteLine(string.Format("Regex: {0}", sNewReg)) 
Regex MyRegex = new Regex(sNewReg, 
    RegexOptions.IgnoreCase 
    | RegexOptions.CultureInvariant 
    | RegexOptions.IgnorePatternWhitespace 
    | RegexOptions.Compiled 
    ); 
string sMg = "<html><head></head><body><!-- #Editable \\\"Body1\\\" --><p>etc etc</p><!-- #Editable \\\"Extra\\\" --></body></html>"; 
Match m = MyRegex.Match(sMg); 
if (m.Success) 
{ 
    System.Diagnostics.Debug.WriteLine(string.Format("{0}", m.Groups["editable"].Value)); 
} 

注意我是如何使用美元符號,以防止逃逸,並在運行時雙引號替換它..

希望這有助於 最好的問候, 湯姆。

+0

長相,我的時間有限僅一行代碼遠離成功! ;( – Stephen 2010-02-18 11:11:26

0

我會建議使用像這樣的東西NVelocity模板引擎。

+0

我是時間限制只有一行代碼遠離成功!:( – Stephen 2010-02-18 11:07:18

+0

...和幾個正則表達式遠離永久維護... – 2010-02-18 11:08:45

+0

不止一行恐怕 – andynormancx 2010-02-18 11:11:19

0

使用MatchEvaluator爲匿名委託你的代碼會像

string html = "<html><head></head><body><!-- #Editable \"Body1\" --><p>etc etc</p><!-- #Editable \"Extra\" --></body></html>"; 
string regions = "<!-- #BeginEditable \"Body1\" -->This is Test Text<!-- #EndEditable --><!-- #BeginEditable \"Extra\" -->This is more test text<!-- #EndEditable -->"; 

Regex oRegex1 = new Regex("<!-- #Editable \"(.*?)\"[^>]*>", RegexOptions.Multiline); 

html = oRegex1.Replace(html, delegate(Match m) { 
    string title = m.Groups[1].Value; 
    Regex oRegex2 = new Regex("<!-- #BeginEditable \"" + title + "\"[^>]*>(.*?)<!-- #EndEditable [^>]*>", RegexOptions.Multiline); 
    return oRegex2.Match(regions).Groups[1].Value; 
});