找到一组单词并用一个单词替换它们

时间:2014-04-10 12:00:52

标签: c# regex string

我正在解析一个字符串,例如

Hello[Left][Left]This is a test string[Left][Left][Left][Left]

我想找到[左] [左]的多个模式并替换它们以使输出变为

Hello[Left x 2]This is a test string[Left x 4]

最有效的方法是什么?

4 个答案:

答案 0 :(得分:1)

这是我的方法:

String input = "Hello[Left][Left]This is a test string[Left][Left][Left][Left]";
MatchCollection c = Regex.Matches(input, "(?:\\[Left\\])+");
StringBuilder output = new StringBuilder();
int start = 0;
foreach (Match m in c)
{
    output.Append(input.Substring(start, m.Index - start));
    output.AppendFormat("[Left x {0}]", m.Length / 6);
    start = m.Index + m.Length;
}
output.Append(input.Substring(start));
Console.Write(output.ToString());

答案 1 :(得分:1)

这是一个更短的版本。

var word = "Left";
var source = "Hello[Left][Left]This is a test string[Left][Left][Left][Left]";
var replaceRegex = new Regex("(\\[" + word + "\\])\\1+");
var result = replaceRegex.Replace(source, delegate(Match m)
{
    return string.Format("[{0} x {1}]"
              , word
              , m.Groups[0].ToString().Length / m.Groups[1].ToString().Length);
});

我使用正则表达式元素\n,其中n引用第n个捕获的组。然后一个简单的MatchEvaluator让我们计算这个单词存在多少个实例。我使用整个匹配组(m.Groups[0])的长度除以捕获组的长度(m.Groups[1]),但您可能想要更改此计算。

你甚至可以捕捉多个单词,不同的单词等...调整正则表达式可以让你在重复单词等之间捕捉到空格......

编辑:,这是一个括号被整合到“单词”中的版本,因为我不喜欢让代码乱丢代码

var word = "[Left]";
var compressedWord = "[Left x {0}]";
var source = "Hello[Left][Left]This is a test string[Left][Left][Left][Left]";
var replaceRegex = new Regex("(" + Regex.Escape(word) + ")\\1+");
var result = replaceRegex.Replace(source, delegate(Match m)
{
    return string.Format(compressedWord
              , m.Groups[0].ToString().Length / m.Groups[1].ToString().Length);
});

答案 2 :(得分:0)

这应该捕获[]和相同的计数事件之间的任何内容。它会匹配括号中的任何内容,如果它们是邻居并且包含相同的文本,则将它们分组。

var data = @"Hello[Left][Left]This is a test string[Left][Left][Left][Left][Left]"; // Outputs: Hello[Left x 2]This is a test string[Left x 5]
//data = @"Hello[Left][Left]This is a test string[Left][Left][Right][Right][Left]"; // Outputs: Hello[Left x 2]This is a test string[Left x 2][Right x 2][Left]

var matches = new Queue<Match>(Regex.Matches(data, @"\[([^]]+?)\]").Cast<Match>());
var builder = new StringBuilder();

var position = 0;
while (matches.Count > 0)
{
    var start = matches.Dequeue();
    var end = start;
    var count = 1;

    while (matches.Count > 0 && start.Value.Equals(matches.Peek().Value) && (end.Index + end.Length) == matches.Peek().Index)
    {
        end = matches.Dequeue();
        count++;
    }

    if (start.Index > position)
    {
        builder.Append(data.Substring(position, start.Index - position)); // Not matched text
    }

    if (count > 1)
    {
        builder.Append(String.Format("[{0} x {1}]", start.Groups[1], count)); // Matched duplicates
    }
    else
    {
        builder.Append(start.Value);  // Matched solo so skipping " x 1"
    }

    position = end.Index + end.Length;
}

var processed = builder.ToString();

答案 3 :(得分:-1)

我希望这个版本适合你

        var relacedText = "Hello[Left][Left]This is a test string[Left][Left][Left][Left]".Replace("[Left]", "#");
        var template = "[Left x {0}]";
        var finalString = "";
        var counter = 0;
        foreach (var c in relacedText)
        {
            if (c == '#')
            {
                counter++;
                continue;
            }
            if (counter > 0)
            {
                finalString += string.Format(template, counter);
                counter = 0;
            }
            finalString += c;

        }
        if (counter > 0)
        {
            finalString += string.Format(template, counter);
        }

        Console.WriteLine(finalString);