If you want to use a single line solution, you can do something like this, but it can be slow for large lines, since it has to find the counter ?? for every match
var result = Regex.Replace(input, @"\?", m => "@p" + input.Take(m.Index).Count(c => c == '?'));
Returns "book_id = @p0 and author_id = @p1 and publisher_id = @p2"
This is the only way to see indext without declaring an external variable.
source share