【问题标题】:c# regex replace but with different replacement value each timec# 正则表达式替换但每次替换值不同
【发布时间】:2016-02-19 21:03:04
【问题描述】:

我有一个这样的字符串:

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

这是一个模板用例。每个查询将被不同的值(即 SQL 结果)替换。是否可以使用正则表达式替换方法来做到这一点?

我正在考虑的解决方案是在第一遍中使用 Regex.Match ,收集所有匹配项,然后在第二遍中使用 string.replace 逐个替换匹配项。有没有更好的方法来解决这个问题?

【问题讨论】:

  • 如果结构是 HTML,您可以使用 HTML 解析器。

标签: c# .net regex


【解决方案1】:
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));

Sql.Execute 是一个占位符函数,用于您调用以执行查询的任何逻辑。完成后,其结果将替换原来的&lt;query&gt;…&lt;/query&gt; 内容。

如果您希望消除查询标记,请使用命名捕获组而不是环视:

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

【讨论】:

    【解决方案2】:

    您可以使用Html Agility Pack 首先获取query 标签,然后用您想要的任何内容替换内部文本:

    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";
      }
    }
    

    您还可以使用字典将模式保存为键,将替换保存为值:

    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];
      }
    }
    

    【讨论】:

      【解决方案3】:

      我们知道正则表达式不适合 html 解析,但我认为您不需要在这里解析 html,只需获取 &lt;query&gt;xxx&lt;/query&gt; 模式中的内容即可。 因此,文档的其余部分是什么并不重要,因为您不想遍历它,也不想验证或更改,什么都没有(根据您的问题)。

      因此,在这种特殊情况下,我会使用正则表达式而不是 html 解析器:

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

      然后用字符串替换方法替换每个匹配项

      【讨论】:

        猜你喜欢
        • 2017-08-22
        • 1970-01-01
        • 2011-03-21
        • 2022-06-12
        • 1970-01-01
        • 2016-07-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多