我需要拿这个字符串:
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)**");
给我组的索引的替换模式是什么?
答案 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
。在这种情况下,不需要使用Match
(m
);我们只想返回连接结果并递增计数器。
答案 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();