我正在尝试替换我的字符串中的模式,其中只应替换标记之间的单词。需要替换的单词位于字典中作为键和值对。
目前我正在尝试这样做:
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();
使用它,它确实取代了但只有第一个&#39;你好&#39;而不是第二个。我想替换每一次'&#39;你好'&#39;标签之间。
非常感谢任何帮助。
答案 0 :(得分:2)
问题是匹配是:
所以,例如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
如果有人想深入研究这个,请告诉我为什么需要一个&#34;列表|&#34;在列表中(因为第一项被忽略),我会很感激。
答案 1 :(得分:1)
这是另一种方法 - 我将字符串解析为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是什么样的。
答案 2 :(得分:0)
这将做你想要的(你目前提供的):
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;
}