簡體   English   中英

C#使用字典替換正則表達式匹配的模式

[英]C# Replace regex matched pattern using dictionary

我正在嘗試替換字符串中的模式,該模式中僅標記之間的單詞應被替換。 需要替換的單詞作為鍵和值對駐留在字典中。

目前,這是我正在嘗試的:

string input = "<a>hello</a> <b>hello world</b> <c>I like apple</c>";
string pattern = (@"(?<=>)(.)?[^<>]*(?=</)");
Regex match = new Regex(pattern, RegexOptions.IgnoreCase);
MatchCollection matches = match.Matches(input);

var dictionary1 = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
dictionary1.Add("hello", "Hi");
dictionary1.Add("world", "people");
dictionary1.Add("apple", "fruit");

string output = "";

output = match.Replace(input, replace => { return dictionary1.ContainsKey(replace.Value) ? dictionary1[replace.Value] : replace.Value; });
Console.WriteLine(output);
Console.ReadLine();

使用它,它確實會替換,但只會替換第一個“ hello”,而不替換第二個。 我想替換標簽之間每次出現的“ hello”。

任何幫助都感激不盡。

問題是匹配項是:

  • 你好
  • 你好,世界
  • 我喜歡蘋果

因此,例如hello world不在您的詞典中。

根據您的代碼,這可能是一個解決方案:

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

public class Program
{
    public static void Main()
    {
        var dictionary1 = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
        dictionary1.Add("hello", "Hi");
        dictionary1.Add("world", "people");
        dictionary1.Add("apple", "fruit");


        string input = "<a>hello</a> <b>hello world</b> <c>I like apple</c>";
        string pattern = ("(?<=>)(.)?[^<>]list|" + GetKeyList(dictionary1) + "(?=</)");
        Regex match = new Regex(pattern, RegexOptions.IgnoreCase);
        MatchCollection matches = match.Matches(input);

        string output = "";

        output = match.Replace(input, replace => {
            Console.WriteLine(" - " + replace.Value);

            return dictionary1.ContainsKey(replace.Value) ? dictionary1[replace.Value] : replace.Value;
        });
        Console.WriteLine(output);
    }

    private static string GetKeyList(Dictionary<string, string> list)
    {
         return string.Join("|", new List<string>(list.Keys).ToArray());
    }
}

小提琴: https : //dotnetfiddle.net/zNkEDv

如果有人想對此進行深入了解,請告訴我為什么我需要“列表|” 在列表中(因為忽略了第一項),我將不勝感激。

這是另一種實現方式-我將字符串解析為XML,然后在字典中選擇包含鍵的元素,然后替換每個元素的值。
但是,您必須具有有效的XML文檔-您的示例缺少根節點。

    var xDocument = XDocument.Parse("<root><a>hello</a> <b>hello world</b> <c>I like apple</c></root>");
    var dictionary1 = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) { { "hello", "Hi" }, { "world", "people" }, { "apple", "fruit" } };

    string pattern = @"\w+";
    Regex match = new Regex(pattern, RegexOptions.IgnoreCase);

    var xElements = xDocument.Root.Descendants()
                      .Where(x => dictionary1.Keys.Any(s => x.Value.Contains(s)));

    foreach (var xElement in xElements)
    {
        var updated = match.Replace(xElement.Value, 
                           replace => {
                                return dictionary1.ContainsKey(replace.Value) 
                                   ? dictionary1[replace.Value] : replace.Value; });
        xElement.Value = updated;
    }
    string output = xDocument.ToString(SaveOptions.DisableFormatting);

這種"\\w+"匹配單詞,而不是空格。
此LINQ選擇元素值包含字典中任何鍵的根節點的后代:

var xElements = xDocument.Root.Descendants().Where(x => dictionary1.Keys.Any(s => x.Value.Contains(s)));

然后,我遍歷返回的XElement可枚舉集合,並將替換的MatchEvaluator應用於字符串值,這要容易得多!

最終輸出是<root><a>Hi</a><b>Hi people</b><c>I like fruit</c></root> 然后,您可以刪除開始和結束<root></root>標記,但是我不知道您的完整XML是什么樣子。

這將做您想要的( 到目前為止提供的內容 ):

private static Dictionary<string, string> dict;
static void Main(string[] args)
{
  dict =
    new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
      {
        { "hello", "Hi" },
        { "world", "people" },
        { "apple", "fruit" }
      };

  var input = "<a>hello</a> <b>hello world</b> apple <c>I like apple</c> hello";
  var pattern = @"<.>([^<>]+)<\/.>";
  var output = Regex.Replace(input, pattern, Replacer);

  Console.WriteLine(output);
  Console.ReadLine();
}

static string Replacer(Match match)
{
  var value = match.Value;
  foreach (var kvp in dict)
  {
    if (value.Contains(kvp.Key)) value = value.Replace(kvp.Key, kvp.Value);
  }
  return value;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM