使用正则表达式删除[]中的标签

时间:2015-07-02 20:52:17

标签: c# regex

作为一个例子,我有这个内容

<tag1><tag2>Test</tag2>[<tag3>[<tag4>TAB1</tag4>]</tag3>]</tab1>
<tag1><tag2>Test</tag2>[<tag3>[<tag5></tag5><tag4>TAB2</tag4>]</tag3>]</tab1>

我希望这次回归

<tag1><tag2>Test</tag2>[[TAB1]]</tab1>
<tag1><tag2>Test</tag2>[[TAB2]]</tab1>

我试过

Regex.Replace(text, "<.*?>", string.Empty)

但这删除了所有标签。我只需删除[]内的内容。

修改

感谢那里的帮助。我最后做了其他的事情,因为我无法通过以下任何方式:因为我有随机标签和变量名。

 public static string PrepareDocument(string input, int posBase = 0)
        {
            int indexFistOpen = input.IndexOf('[', posBase);
            int indexFistClose = input.IndexOf(']', indexFistOpen);
            int indexLastClose = input.IndexOf(']', indexFistClose + 1);
            int tagLength = (indexLastClose - indexFistOpen) + 1;

            var txWithTags = input.Substring(indexFistOpen, tagLength);
            var text = Regex.Replace(txWithTags, "<.*?>", string.Empty);

            input = input.Remove(indexFistOpen, tagLength);
            input = input.Insert(indexFistOpen, text);

            posBase = input.IndexOf(text, posBase) + text.Length;
            if (input.IndexOf('[', posBase) > -1)
            {
                input = PrepareDocument(input, posBase);
            }

            return input;
        }

3 个答案:

答案 0 :(得分:3)

一种方法是找到最外面的方括号,并仅删除匹配部分中的标签。

为此,您需要使用balancing groups在嵌套(或非)括号中查找子字符串。然后,您只需将替换委托给具有MatchEvaluator而不是固定字符串的函数。

public static void Main()
{
    string html = "<tag1><tag2>Test</tag2>[<tag3>[<tag4>TAB1</tag4>]</tag3>]</tab1>\n"
                + "<tag1><tag2>Test</tag2>[<tag3>[<tag5></tag5><tag4>TAB2</tag4>]</tag3>]</tab1>";

    string pattern = @"\[(?>[^][]+|(?<open>\[)|(?<close-open>]))*(?(open)(?!))]";
    MatchEvaluator evaluator = new MatchEvaluator(RemoveTags);

    Console.WriteLine(Regex.Replace(html, pattern, evaluator));      
}

public static string RemoveTags(Match match)
{
    return Regex.Replace(match.Value, @"<[^>]*>", string.Empty);   
}

另一种可以提高性能的方法(因为C#是一种编译语言)是用基本的字符串操作编写自己的字符串解析器。你需要的只是一个计数器,知道方括号何时平衡。当找到一个开括号时,你增加计数器,当找到一个右括号时你减少计数器,当计数器等于零时,括号是平衡的。 (请注意,这或多或少是平衡组模式的作用)。

答案 1 :(得分:2)

var regex = new Regex(@"(?<=\[)(</?tag\d>)+|(</?tag\d>)+(?=\])");

var src1 = "<tag1><tag2>Test</tag2>[<tag3>[<tag4>TAB1</tag4>]</tag3>]</tab1>";
var src2 = "<tag1><tag2>Test</tag2>[<tag3>[<tag5></tag5><tag4>TAB2</tag4>]</tag3>]</tab1>";

var result1 = regex.Replace(src1, "");
var result2 = regex.Replace(src2, "");

结果如下:

Result

编写正则表达式的方式可能不那么冗长。无论如何,我使用lookbefore (?<=\[)和lookahead (?=\])断言来确定何时匹配标记元素。

答案 2 :(得分:0)

使用Regex是一个很好的解决方案,但它比刚刚写过的方法慢了3倍:

        string s = @"<tag1><tag2>Test</tag2>[<tag3>[<tag5></tag5><tag4>TAB2</tag4>]</tag3>]</tab1>";
        var result = removeTagsInBrackets(s);
        Console.WriteLine(result);

用法:

<tag1><tag2>Test</tag2>[[TAB2]]</tab1>

输出:$ vmstat | python -c 'import sys; print sys.stdin.readlines()[-1].split()[-2]' 95

同时检查:Test on performance