-1

我有以下 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

4 回答 4

0

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

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

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

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

于 2012-07-18T10:03:08.137 回答
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>示例中缺少一个。

于 2012-07-18T10:03:33.747 回答
0

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

于 2012-07-18T10:05:20.547 回答
0

为您的正则表达式创建一个循环:

var rgx = new Regex(@"<div class=""sp-body"" title=""(.*?)"">(.*?)</div>");
while (rgx.IsMatch(outstring))
{
    outstring = rgx.Replace(outstring, "[spoiler=$1]$2[/spoiler]");
}
于 2012-07-18T10:23:04.397 回答