【问题标题】:c# Replace text within curly brackets, including the curly bracketsc#替换大括号内的文本,包括大括号
【发布时间】:2019-01-30 19:49:27
【问题描述】:

我正在尝试替换一个字符串,用大括号括起来。

如果我使用 Regex 类提供的 Replace 方法并且我没有指定大括号,则可以正确找到并替换字符串,但如果我像这样指定大括号:{{FullName}},则文本为原封不动。

   var pattern = "{{" + keyValue.Key + "}}";
   docText = new Regex(pattern, RegexOptions.IgnoreCase).Replace(docText, keyValue.Value);

以这个字符串为例

Dear {{FullName}}

我想用John替换它,这样文本就变成了这样:

Dear John.

如何表达正则表达式,以便找到并正确替换字符串?

【问题讨论】:

  • 我无法通过this code 重现您的问题。第三行之后的docText 变量将是Hello there John!
  • 我认为现在还不清楚。 keyValue 是什么?请提供所有详细信息以重现问题。
  • 另外,您可能需要查找RegEx.Escape 来清理您的模式字符串,以便您从字面上匹配“模式”的所有字符。你实际上没有正则表达式。例如:{ 在 RegEx 语言中表示特殊的含义。
  • 是的,{{8}} 不会匹配 {{8}},是的,所以应该转义 {s。如果不确定keyValue.Key 中有哪些字符,Regex.Escape 总是一个好主意。
  • 关键只是问题的一半。 {{foo}}的大括号也是一个问题,必须变成\{\{foo\}\}。只需传递 new Regex(Regex.Escape(pattern), ...) 这会将您所谓的 pattern (实际上根本不是模式,而是要搜索的文字文本)变成实际的正则表达式 pattern .

标签: c# regex


【解决方案1】:

如果键只是一个字符串,则不需要正则表达式。只需将“{{FullName}}”替换为“John”即可。示例:

string template = "Dear {{FullName}}";
string result = template.Replace("{{" + keyValue.Key + "}}", keyValue.Value);

编辑:解决这不起作用的问题...

下面是一个完整的例子。你可以在https://dotnetfiddle.net/wnIkvf运行它

using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        var keyValue = new KeyValuePair<string,string>("FullName", "John");
        string docText = "Dear {{FullName}}";
        string result = docText.Replace("{{" + keyValue.Key + "}}", keyValue.Value);
        Console.WriteLine(result);
    }
}

【讨论】:

  • 对不起,我试过了,但它不起作用。使用的文本来自一个word文件(.docx),它是否改变了replace方法的工作方式?
  • @eddy 我添加了一个 dotnetfiddle 来演示它的工作原理。
  • @eddy 假设 docText 最终成为一个没有奇怪的 unicode 字符或控制序列的不起眼的字符串,那么它应该没问题。检查调试器中的 docText 以查看其中的内容。
  • 对不起@Wyck 但这是一匹一招制小马……看我的回答。 :-)
【解决方案2】:

寻找"Dear {{FullName}}""Dear John"

不是正则表达式解决方案...但有时我更喜欢这样做。

string s = "Dear {{FullName}}";
// use regex to replace FullName like you mentioned before, then...
s.Replace("{",string.empty);
s.Replace("}",string.empty);

【讨论】:

  • 我认为这是不对的。我希望 OP 想要字符串插值,这意味着他们希望 "FullName {{FullName}}" 产生 "FullName John"
【解决方案3】:
var keyValue = new KeyValuePair<string,string>("FullName", "John");
var pattern = "{{" + keyValue.Key + "}}";
Console.WriteLine(new Regex(Regex.Escape(pattern), RegexOptions.IgnoreCase).Replace("Dear {{FullName}}", keyValue.Value));

输出:

Dear John

【讨论】:

    【解决方案4】:

    如果您确实想使用正则表达式,则使用Regex.Escape 转义您的文字以将其转换为正则表达式模式。

    var keyValue = new KeyValuePair<string,string>("FullName", "John");
    string docText = "Dear {{FullName}}";
    var pattern = "{{" + keyValue.Key + "}}";
    docText = new Regex(Regex.Escape(pattern), RegexOptions.IgnoreCase).Replace(docText, keyValue.Value);
    

    docText 将是 Dear John

    【讨论】:

    • Regex.Escape 产生这个字符串\{\{FullName}}
    【解决方案5】:

    我认为您真正想做的是替换文档中的多个内容。

    为此,请使用我提供的正则表达式模式,但也使用正则表达式替换匹配评估器委托。这样做的目的是,可以主动为每个项目评估每个匹配项,并根据 C# 逻辑替换适当的项目。

    这是一个包含两个可能的关键字设置的示例。

    string text = "Dear {{FullName}}, I {{UserName}} am writing to say what a great answer!";
    
    string pattern = @"\{\{(?<Keyword>[^}]+)\}\}";
    
    var replacements 
       = new Dictionary<string, string>() { { "FullName", "OmegaMan" }, { "UserName", "eddy" } };
    
    Regex.Replace(text, pattern, mt =>
    {
    
        return replacements.ContainsKey(mt.Groups["Keyword"].Value)
               ? replacements[mt.Groups["Keyword"].Value]
               : "???";
    
    }
    );
    

    结果

    亲爱的 OmegaMan,我写信是想表达一个多么棒的答案!


    前面的例子使用

    • Match Evaluator Delegate
    • 命名匹配捕获组(?&lt;{Name here}&gt; …)
    • Set Negation [^ ] 表示匹配,直到找到被否定的项目,在本例中为结束卷曲 }

    【讨论】:

      猜你喜欢
      • 2019-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-27
      • 1970-01-01
      相关资源
      最近更新 更多