我正在处理文件,以便用前缀和后置字符串(例如“#”和“。”)替换预定义关键字列表,如下所示:
“Word Word2 anotherWord和其他一些东西”应该成为“#Word。#Word2。#anotherWord。以及其他一些东西”
我的密钥是唯一的,并且处理从最长密钥到最小密钥的密钥,所以我知道包含只能在已经存在
但是,如果我有密钥包含(例如Word2
包含Word
),并且我有
"Word Word2 anotherWord and some other stuff"
.Replace("anotherWord", "#anotherWord.")
.Replace("Word2", "#Word2.")
.Replace("Word", "#Word.")
我得到以下结果:
<#>“#Word。## Word.2。#another#Word ..以及其他一些东西”
当然,我的做法并非如此。那么,如果它不包含在另一个键中,那么确保我只替换字符串中的键的方法是什么?我试过RegExp但没找到正确的方法。还是有另一种解决方案?
答案 0 :(得分:1)
如果性能不是关键要求,只需使用带有字边界的正则表达式:
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace Subst
{
public class Program
{
public static void Main(string[] args)
{
var map = new Dictionary<string, string>{
{"Word", "#Word."},
{"anotherWord", "#anotherWord."},
{"Word2", "#Word2."}
};
var input = "Word Word2 anotherWord and some other stuff";
foreach(var mapping in map) {
input = Regex.Replace(input, String.Format("\\b{0}\\b", mapping.Key), Regex.Escape(mapping.Value));
}
Console.WriteLine(input);
}
}
}
答案 1 :(得分:0)
一种方法是使用
string myString = String.Format("ORIGINAL TEXT {1} {2}", "TEXT TO PUT INSIDE CURLY BRACKET 1", "TEXT TO PUT IN CURLY BRACKET 2");
//Result: "ORIGINAL TEXT TEXT TO PUT INSIDE CURLY BRACKET 1 TEXT TO PUT IN CURLY BRACKET 2"
但是,这需要您的原始文本首先包含大括号。
相当混乱,但你总是可以用Replace替换你要找的单词,然后同时更改卷曲的支持。这可能是一个更好的方法,但我现在无法想到它。
答案 2 :(得分:0)
我建议直接实施,例如
private static String MyReplace(string value, params Tuple<string, string>[] substitutes) {
if (string.IsNullOrEmpty(value))
return value;
else if (null == substitutes || !substitutes.Any())
return value;
int start = 0;
StringBuilder sb = new StringBuilder();
while (true) {
int at = -1;
Tuple<string, string> best = null;
foreach (var pair in substitutes) {
int index = value.IndexOf(pair.Item1, start);
if (index >= 0)
if (best == null ||
index < at ||
index == at && best.Item1.Length < pair.Item1.Length) {
at = index;
best = pair;
}
}
if (best == null) {
sb.Append(value.Substring(start));
break;
}
sb.Append(value.Substring(start, at - start));
sb.Append(best.Item2);
start = best.Item1.Length + at;
}
return sb.ToString();
}
测试
string source = "Word Word2 anotherWord and some other stuff";
var result = MyReplace(source,
new Tuple<string, string>("anotherWord", "#anotherWord."),
new Tuple<string, string>("Word2", "#Word2."),
new Tuple<string, string>("Word", "#Word."));
Console.WriteLine(result);
结果:
#Word. #Word2. #anotherWord. and some other stuff
答案 3 :(得分:0)
正则表达式替代(顺序无关紧要):
var result = Regex.Replace("Word Word2 anotherWord and some other stuff", @"\b\S+\b", m =>
m.Value == "anotherWord" ? "#anotherWord." :
m.Value == "Word2" ? "#Word2." :
m.Value == "Word" ? "#Word." : m.Value)
或分开:
string s = "Word Word2 anotherWord and some other stuff";
s = Regex.Replace(s, @"\b" + Regex.Escape("anotherWord") + @"\b", "#anotherWord.");
s = Regex.Replace(s, @"\b" + Regex.Escape("Word2") + @"\b", "#Word2.");
s = Regex.Replace(s, @"\b" + Regex.Escape("Word") + @"\b", "#Word.");
答案 4 :(得分:0)
使用双循环方法解决问题如下......
List<string> keys = new List<string>();
keys.Add("Word1"); // ... and so on
// IMPORTANT: algorithm works only when we are sure that one key cannot be
// included in another key with higher index. Also, uniqueness is
// guaranteed by construction, although the routine would work
// duplicate key...!
keys = keys.OrderByDescending(x => x.Length).ThenBy(x => x).ToList<string>();
// first loop: replace with some UNIQUE key hash in text
foreach(string key in keys) {
txt.Replace(key, string.Format("!#someUniqueKeyNotInKeysAndNotInTXT_{0}_#!", keys.IndexOf(key)));
}
// second loop: replace UNIQUE key hash with corresponding values...
foreach(string key in keys) {
txt.Replace(string.Format("!#someUniqueKeyNotInKeysAndNotInTXT_{0}_#!", keys.IndexOf(key)), string.Format("{0}{1}{2}", preStr, key, postStr));
}
答案 5 :(得分:-1)
您可以将字符串拆分为''并循环显示字符串数组。将数组的每个索引与替换字符串进行比较,然后在完成时将它们连接起来。
string newString = "Word Word2 anotherWord and some other stuff";
string[] split = newString.Split(' ');
foreach (var s in split){
if(s == "Word"){
s = "#Word";
} else if(s == "Word2"){
s = "#Word2";
} else if(s == "anotherWord"){
s = "#anotherWord";
}
}
string finalString = string.Concat(split);