Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ssis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C使用字典替换正则表达式匹配模式_C#_.net_Regex - Fatal编程技术网

C# C使用字典替换正则表达式匹配模式

C# C使用字典替换正则表达式匹配模式,c#,.net,regex,C#,.net,Regex,我试图替换字符串中的一个模式,其中只应替换标记之间的单词。需要替换的单词作为键和值对驻留在字典中 目前我正在尝试: string input = "<a>hello</a> <b>hello world</b> <c>I like apple</c>"; string pattern = (@"(?<=>)(.)?[^<>]*(?=</)"); Regex match = new Regex(p

我试图替换字符串中的一个模式,其中只应替换标记之间的单词。需要替换的单词作为键和值对驻留在字典中

目前我正在尝试:

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());
    }
}
小提琴:


如果有人想深入研究这个问题,请告诉我为什么我需要一个列表,因为第一项被忽略了,我会很感激的。

这是另一种方法-我将字符串解析为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);
然后,我遍历返回的XElement可枚举集合,并将替换MatchEvaluator应用于字符串值,这要容易得多


最后的结果是人们喜欢水果。然后,您可以删除开始、结束和标记,但我不知道完整的XML是什么样子。

这将根据您目前提供的内容实现您想要的功能:


我认为您的正则表达式与标记之间的值相匹配,因此您尝试替换的匹配项是hello,hello world和我喜欢apple。你是在试着匹配单个单词吗?所以你的输出应该是hi hi people I like fruit?在XML上使用正则表达式通常被认为是个坏主意。是的,这正是我想要的输出。我的正则表达式是问题所在吗?是的,你的正则表达式不太正确,但我似乎想不出符合你要求的东西!我的正则表达式技能有些生疏…这里有一把小提琴,我把它们打印出来:这肯定告诉OP问题出在哪里。。。您是否计划提供解决方案?将@mikemccaughant这项工作做得很好!但是,我不清楚您在中做了什么来匹配模式?@d.him基本上我正在根据字典建立一个单词列表。那么最后的表达式是?[^]list | hello | world | apple=
var xElements = xDocument.Root.Descendants().Where(x => dictionary1.Keys.Any(s => x.Value.Contains(s)));
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;
}