c#替换字符串,如果它不是子字符串

时间:2018-05-30 13:19:19

标签: c# replace substring

我正在处理文件,以便用前缀和后置字符串(例如“#”和“。”)替换预定义关键字列表,如下所示:

  “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但没找到正确的方法。还是有另一种解决方案?

6 个答案:

答案 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);