MD Luffy
MD Luffy

Reputation: 556

c# regex replace but with different replacement value each time

I have a string like this:

<div>
<query>select * from table1</query>
</div>
<div>
<query>select * from table2</query>
</div>

This is a templating usecase. Each query will be replaced by a different value (ie SQL result). Is it possible to use Regex Replace method to do this ?

The solution I'm thinking of is to use Regex.Match in the first pass, collect all the matches and then use string.replace in the second pass to replace the matches one by one. Is there a better way to solve this ?

Upvotes: 0

Views: 176

Answers (3)

Douglas
Douglas

Reputation: 54877

var source = 
@"<div>
<query>select * from table1</query>
</div>
<div>
<query>select * from table2</query>
</div>";

var result = Regex.Replace(
   source,
   "(?<=<query>).*?(?=</query>)",
   match => Sql.Execute(match.Value));

The Sql.Execute is a placeholder function for whatever logic you invoke to execute your query. Upon completion, its results will substitute the original <query>…</query> contents.

If you want the query tags to be eliminated, then use a named capture group rather than lookarounds:

var result = Regex.Replace(
    source,
    "<query>(?<q>.*?)</query>",
    match => Sql.Execute(match.Groups["q"].Value));

Upvotes: 2

ocuenca
ocuenca

Reputation: 39326

You could use Html Agility Pack to get first the query tags and replace the inner text with whatever you want:

var html = new HtmlDocument();
html.Load(filepath);
var queries = html.DocumentNode.SelectNodes("//query");
foreach(var node in queries)
{
  if(node.InnerText=="select * from table1")
  {
    node.InnerText="your result";
  }
}

You could also use a dictionary to save the pattern as key and the replacement as value:

var dict = new Dictionary<string, string>();
dict.Add("select * from table1","your result");
//...

var html = new HtmlDocument();
html.Load(filepath);
var queries = html.DocumentNode.SelectNodes("//query");
foreach(var node in queries)
{
  if(dict.Keys.Contains(node.InnerText))
  {
    node.InnerText=dict[node.InnerText];
  }
}

Upvotes: 1

tede24
tede24

Reputation: 2354

We know regex is not good for html parsing, but I think you don't need to parse html here, but simply get what's inside <query>xxx</query> pattern. So it doesn't matter what is the rest of the document as you don't want to traverse it, nor validate nor change, nothing (according with your question).

So, in this particular case, I would use regex more than html parser:

var pattern = "<query>.+<\/query>";

And then replace every match with string Replace method

Upvotes: 0

Related Questions