【问题标题】:Extract String between 2 dollar sign提取 2 美元符号之间的字符串
【发布时间】:2019-02-13 20:41:27
【问题描述】:

我有一个包含变量的字符串。但我需要用我在数据库中的内容替换name

string text = "hello $$name$$, good morning"

如何使用Regex 提取name

这仅适用于我有单个 $

var MathedContent = Regex.Match((string)bodyObject, @"\$.*?\$");

【问题讨论】:

  • 这是什么语言? /\$\$([^$])\$\$/ 应该匹配
  • 我正在使用 C#。
  • 如果您打算使用name 来获取您在其他地方拥有的一些值,您可以考虑使用Regex.Replace((string)bodyObject, @"\$\$(\w+)\$\$", m => dct[m.Groups[1].Value]),但您需要准备好包含所有可能键的dct 字典。
  • 您需要替换整个$$name$$ 还是只替换name 并留下$$

标签: c# .net regex


【解决方案1】:

您可以使用 3 个不同的组定义正则表达式 "(\$\$)(.*?)(\$\$)"

 "(\$\$)(.*?)(\$\$)"
 ^^^^^^|^^^^^|^^^^^^
    $1    $2    $3

然后,如果您只需要简单的替换,您可以执行以下操作:

string replacedText = Regex
    .Replace("hello $$name$$, good morning", @"(\$\$)(.*?)(\$\$)", "replacement");
//hello replacement, good morning

或与其他组结合

string replacedText = Regex
    .Replace("hello $$name$$, good morning", @"(\$\$)(.*?)(\$\$)", "$1replacement$3");
//hello $$replacement$$, good morning

另一方面,如果您需要更多控制权,可以执行以下操作(tnx to Wiktor):

IDictionary<string, string> factory = new Dictionary<string, string>
{
    {"name", "replacement"}
};

string replacedText = Regex.Replace(
    "hello $$name$$, good morning",
    @"(?<b>\$\$)(?<replacable>.*?)(?<e>\$\$)",
    m => m.Groups["b"].Value + factory[m.Groups["replacable"].Value] + m.Groups["e"].Value);
//hello $$replacement$$, good morning

【讨论】:

  • 我认为您也可以使用 2 个捕获组 (\$\$).*?(\$\$) 并在替换中使用 $1replacement$2
【解决方案2】:

您的问题有点模棱两可,您是要替换整个$$name$$ 还是查找美元之间的字符串。

这是两者的工作代码:

将 $$name$$ 替换为 Bob

    string input = "hello $$name$$, good morning";
    var replaced = Regex.Replace(input, @"(\$\$\w+\$\$)", "Bob");
    Console.WriteLine($"replaced: {replaced}");

打印replaced: hello Bob, good morning

从字符串中提取名称:

    string input = "hello $$name$$, good morning";
    var match = Regex.Match(input, @"\$\$(\w+)\$\$").Groups[1].ToString();
    Console.WriteLine($"match: {match}");

打印match: name

【讨论】:

    【解决方案3】:

    如果要捕获$$ 分隔符之间的文本但排除$$ 本身,可以使用lookaround(?&lt;=\$\$).*?(?=\$\$)

    Lookarounds 是零长度的断言(很像\b),它匹配字符但不将它们包含在结果中。 (?&lt;=XXX)YYY 匹配YYY,条件是它之前是XXX。同样,YYY(?=ZZZ) 匹配 YYY,条件是它跟随 ZZZ

    var match = Regex.Match("hello $$name$$, good morning", @"(?<=\$\$).*?(?=\$\$)");
    Console.WriteLine(match.Value);   // outputs "name"
    

    【讨论】:

      【解决方案4】:
      string input = "hello $$name$$, good morning";
      Regex rx = new Regex(@"(?<=\$\$)(.*?)(?=\$\$)");
      
      Console.WriteLine(rx.Match(input).Groups[1].Value); 
      

      结果:

      name
      

      【讨论】:

        【解决方案5】:

        使用否定集[^ ]。比如[^$]+,我们将匹配到下一个$

        string text = "hello $$name$$, good morning";
        
        Regex.Replace(text, @"\$\$[^$]+\$\$", "Jabberwocky");
        

        结果:

         hello Jabberwocky, good morning
        

        更冗长但更容易阅读而无需转义,模式[$]{2}[^$]+[$]{2}

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-08-21
          • 2011-01-05
          • 2016-08-20
          • 1970-01-01
          • 2021-12-15
          • 1970-01-01
          相关资源
          最近更新 更多