Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 替换C中的正则表达式匹配集合#_C#_Regex_Performance_Replace - Fatal编程技术网

C# 替换C中的正则表达式匹配集合#

C# 替换C中的正则表达式匹配集合#,c#,regex,performance,replace,C#,Regex,Performance,Replace,我需要在文本中找到以[和]开头的所有内容,并用函数返回的值替换它。下面是我正在做的一个例子: public string ProcessTemplate(string input) { return Regex.Replace(input, @"\[(.*?)\]", new MatchEvaluator(delegate(Match match) { return ProcessBlock(match.Re

我需要在文本中找到以[和]开头的所有内容,并用函数返回的值替换它。下面是我正在做的一个例子:

    public string ProcessTemplate(string input)
    {
        return Regex.Replace(input, @"\[(.*?)\]", new MatchEvaluator(delegate(Match match)
            {
                return ProcessBlock(match.Result("$1"));
            }));
    }

    public string ProcessBlock(string value)
    {
        return Block.FromString(value).Process();
    }
现在,我的问题是何时需要编辑块。所以我想找到块,编辑它们,然后在文本中替换它们

因此,我创建了一个块列表,并将
ProcessTemplate
方法分为两种方法:
FindBlocks
ReplaceBlocks

    public void FindBlocks(string input)
    {
        Input = input;

        foreach (Match match in Regex.Matches(input, @"\[(.*?)\]"))
            Blocks.Add(Block.FromString(match.Result("$1")));
    }

    public string ReplaceBlocks()
    {
        string input = Input;

        foreach (Block block in Blocks)
            input = input.Replace("[" + block.OrginalText + "]", block.Process);

        return input;
    }

    public IList<Block> Blocks
    {
        get;
        set;
    }

    public string Input
    {
        get;
        set;
    }
public void FindBlocks(字符串输入)
{
输入=输入;
foreach(Regex.Matches中的匹配(输入@“\[(.*?\])”)
Block.Add(Block.FromString(match.Result($1));
}
公共字符串替换块()
{
字符串输入=输入;
foreach(块中的块)
输入=输入。替换(“[”+block.OrginalText+“]”,block.Process);
返回输入;
}
公共住宅大厦
{
得到;
设置
}
公共字符串输入
{
得到;
设置
}
它正在工作,但问题是它相当慢。我用
System.Diagnostics.Stopwatch
测量了每个部分,发现
ReplaceBlocks
方法中的
String.Replace
非常慢

我怎样才能改进它

谢谢

我觉得很慢

在完成概要分析之前不要进行优化。找出代码慢的原因,然后优化这些部分


使用StringBuilder替换ReplaceBlock中的字符串可能会提高性能,因为每次执行字符串时,replace都必须取消分配字符串并重新分配字符串。字符串生成器不需要这样做

将ReplaceBlock的内容替换为以下内容

// This will require a reference to System.Text
StringBuilder input =new StringBuilder(Input);
  foreach (Block block in Blocks)
  {
    input = input.Replace("[" + block.OrginalText + "]", block.Process);
  }
  return input.ToString();

我还发现用for循环替换foreach循环更快。

太棒了!可能更快的一件事是在最初匹配每个块时存储其字符偏移量。然后通过子字符串替换该字符范围,而不是使用字符串。替换-应该更快。当然,如果替换内容的长度与原始内容的长度不同,则每次替换后都必须使用该差异更新偏移量。更多的簿记,但最终可能会更快。@Kevingesner:我尝试过:“输入=输入。子字符串(0,block.Position)+block.Process()+输入。子字符串(block.Position+block.Length);”但它不起作用。。。block.Position=match.Index,block.Length=match.Length。你知道为什么它不起作用吗?我不明白是什么原因导致你放弃了第一种似乎是正确的解决方案的方法。你能详细说明吗?马克是对的:这正是MatchEvaluator的作用。另外,如果您想要第一个捕获组的内容,
match.Groups[1]
match.Result(“$1”)
更有效。