我正在解析一个字符串,例如
Hello[Left][Left]This is a test string[Left][Left][Left][Left]
我想找到[左] [左]的多个模式并替换它们以使输出变为
Hello[Left x 2]This is a test string[Left x 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);