6

我需要接受这个字符串:

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

5 回答 5

7

您可以使用带有 a 的方法Regex.Replace以及MatchEvaluator一个计数器变量:

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(which is m); 我们只想返回连接的结果并增加计数器。

于 2013-03-05T00:59:21.140 回答
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"

这是我可以看到在不声明外部变量的情况下获取索引的唯一方法。

于 2013-03-05T00:59:29.173 回答
0

我使用 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();
于 2013-03-05T03:52:41.410 回答
0

我想我可能有什么...

这个想法是首先将每个索引放在您想要索引的每个位置:

Ñ123456Ñ

对于此示例,总共有 6 个项目要索引,因此它是由 Ñ (或查找文本中其他任何地方没有的其他字符)包围的所有数字,最多 6 个。

然后你手动制作第一个Ñ1Ñ,这样正则表达式就有一个起点。这样,算法可以找到最后一个索引并使用它来确定下一个索引:

寻找: (Ñ)([0-9])(Ñ)(([^Ñ]|\r?\n)*?)(Ñ)([0-9]*)\2([0-9])([0-9]*)(Ñ)

代替: $1$2$3$4$6$8$10

文本示例:

Ñ1Ñ
Ñ123456Ñ
Ñ123456Ñ
Ñ123456Ñ
Ñ123456Ñ
Ñ123456Ñ

更换一次后:

Ñ1Ñ
Ñ2Ñ
Ñ123456Ñ
Ñ123456Ñ
Ñ123456Ñ
Ñ123456Ñ

再次更换后:

Ñ1Ñ
Ñ2Ñ
Ñ3Ñ
Ñ123456Ñ
Ñ123456Ñ
Ñ123456Ñ

“全部替换”功能对此不起作用,因为它必须一一查找和替换,但我认为它可以完成工作。

然后你只需要删除所有临时的Ñ字符就可以了。

免责声明:解决“中间”文本中的换行符的部分\r?\n- 是为与 Atom 编辑器一起工作的,因此可能需要针对其他情况进行一些调整。我相信它实际上可以完全删除,因为它包含在 中[^Ñ],但我不确定它是否适用于其他系统。


对于多于一位的索引:

寻找: (Ñ)([0-9]{2})(Ñ)(([^Ñ]|\r?\n)*?)(Ñ)([0-9][0-9])*\2([0-9]{2})([0-9][0-9])*(Ñ)

代替: $1$2$3$4$6$8$10

文本示例:

Ñ01Ñ
Ñ0102030405060708091011121314151617Ñ
Ñ0102030405060708091011121314151617Ñ
Ñ0102030405060708091011121314151617Ñ
...
于 2021-09-13T11:12:18.023 回答
-1

未经测试:

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

一条较长的线,但并非完全不合理。

于 2013-03-05T00:49:07.290 回答