C#正则表达式。嵌套标签。匹配剧透并将它们转换为bbcode

时间:2012-07-18 09:52:08

标签: c# regex tags nested bbcode

我有以下html代码,它们嵌套到3级:

<div class="sp-wrap">
    <div class="sp-body" title="FAQ">
        Some text
        <div class="sp-wrap">
            <div class="sp-body" title="title1"> // Level 2
            Text1...
            </div>
        </div>
        <div class="sp-wrap">
            <div class="sp-body" title="title2"> // Level 2
            Text2...
            </div>
        </div>
        <div class="sp-wrap">
            <div class="sp-body" title="title3"> // Level 2
            Text3...
            <div class="sp-wrap">
                <div class="sp-body" title="title4"> // Level 3
                Text4...
                </div>
            </div>
        </div>
    </div>
</div>

我需要将div标签替换为bbcode,而我的正则表达式只能用于非嵌套的剧透:

Regex.Replace(outstring, 
              @"<div class=""sp-body"" title=""(.*?)"">(.*?)</div>", 
              "[spoiler=$1]$2[/spoiler]", 
              RegexOptions.Singleline);

4 个答案:

答案 0 :(得分:0)

你的代码的问题是它只会替换第一次出现的div和下一个最接近/ div出现的div

<div>                    // replaced
    <div>                // not replaced 
    </div>               // replaced
</div>                   // not replaced

一种方法是将其加载到XML中,然后仅使用XPATH修改您感兴趣的节点。如果是HTML,您还可以使用HTML解析器,然后使用CSS选择器。

您可以轻松修改开场div(通过与类匹配),但正则表达式无法知道哪个是相应的结尾div。

答案 1 :(得分:0)

没有测试,但这个想法应该有效:

string s1 = Regex.Replace(outstring, @"<div class=""sp-body"" title=""(.*?)"">", "[spoiler=$1]", RegexOptions.Singleline);
string s2 = Regex.Replace(s1, @"</div>", "[/spoiler]", RegexOptions.Singleline);

修改

string s1 = Regex.Replace(outstring, @"<div class=""sp-wrap"">\s*<div class=""sp-body"" title=""(.*?)"">", "[spoiler=$1]", RegexOptions.Singleline);
string s2 = Regex.Replace(s1, @"</div>\s*</div>", "[/spoiler]", RegexOptions.Singleline);

应该产生类似

的东西
[spoiler=FAQ]
    Some text
    [spoiler=title1] // Level 2
        Text1...
        [/spoiler]
    [spoiler=title2] // Level 2
        Text2...
        [/spoiler]
    [spoiler=title3] // Level 2
        Text3...
        [spoiler=title4] // Level 3
            Text4...
            [/spoiler]
    [/spoiler]
</div>

正如你所看到的那样,它并没有完美缩进(可以修复,我猜)并且在示例中检测到一个缺失</div>

答案 2 :(得分:0)

使用Regex方法尚未完全完成此任务。使用Html Agility Pack解析Html

答案 3 :(得分:0)

为你的正则表达式制作一个循环:

var rgx = new Regex(@"<div class=""sp-body"" title=""(.*?)"">(.*?)</div>");
while (rgx.IsMatch(outstring))
{
    outstring = rgx.Replace(outstring, "[spoiler=$1]$2[/spoiler]");
}