如何解决以下问题?
我正在创建一个简单的内容管理系统,其中有一个带有特定标记的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
我已经在这里开始了代码。但是我在使用Regex Replace功能时遇到了问题,该功能应该位于For / Each的最底层....
//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
//
//
//
}
答案 0 :(得分: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);
}
答案 1 :(得分: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)); }
请注意我必须使用美元符号来防止转义,并在运行时将其替换为双引号。
希望这有帮助, 最好的祝福, 汤姆。
答案 2 :(得分:0)
我建议使用类似NVelocity的模板引擎来处理这类事情。
答案 3 :(得分: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;
});