正则表达式用匹配索引替换字符

时间:2013-03-05 00:30:20

标签: c# regex replace

我需要拿这个字符串:

book_id = ? and author_id = ? and publisher_id = ?

并将其转换为此字符串:

book_id = @p1 and author_id = @p2 and publisher_id = @p3

使用此代码:

Regex.Replace(input, @"(\?)", "@p **(index of group)**");

给我组的索引的替换模式是什么?

4 个答案:

答案 0 :(得分:3)

您可以使用MatchEvaluator的{​​{3}}以及计数器变量:

string input = "book_id = ? and author_id = ? and publisher_id = ?";
string pattern = @"\?";
int count = 1;
string result = Regex.Replace(input, pattern, m => "@p" + count++);

m =>部分是MatchEvaluator。在这种情况下,不需要使用Matchm);我们只想返回连接结果并递增计数器。

答案 1 :(得分:0)

未测试:

int n, i=1; while( (n=input.IndexOf("?")) != -1) { input = input.Substring(0,n-1) + "@p" + (++i) + input.Substring(n+1); }

很长的路线,但并非完全不合理。

答案 2 :(得分:0)

如果你想要一个单行解决方案,你可以做类似的事情,但对于大字符串可能会很慢,因为它必须找到“?”的计数。每场比赛

 var result = Regex.Replace(input, @"\?", m => "@p" + input.Take(m.Index).Count(c => c == '?'));

返回"book_id = @p0 and author_id = @p1 and publisher_id = @p2"

这是我在没有声明外部变量的情况下获得indext的唯一方法。

答案 3 :(得分:0)

我写了一个项目来测试其他答案和我自己的答案。你可以得到它here 结论:
- linq解决方案是最快的 - 正则表达式解决方案最优雅 - 我使用StringBuilder的解决方案并不错,但不是最快也不是最优雅:(

这是我的解决方案:

var count = 1;
var sb = new StringBuilder(input);
for (int i = 0; i < sb.Length; i++)
{
    if (sb[j] == '?')
    {
        sb.Remove(i, 1);
        sb.Insert(i, "@p" + (count++));
        i += 3;
    }
}
result = sb.ToString();