【问题标题】:Issue when replacing strings替换字符串时的问题
【发布时间】:2020-03-15 12:47:47
【问题描述】:

要求执行以下操作的最佳实践,在 C# 中使用此字符串:

string sentence = "我昨晚在看电视,而她在看书,而你在玩电子游戏";

我正在尝试将其自动替换为以下内容:

你昨晚在看电视,而她正在看书,在玩电子游戏”

这里的问题是我不能使用

sentence.Replace("I was", "you were").Replace("you were", "I was")

因为最后一句话看起来很糟糕: “我在看电视,而她在看书,在玩电子游戏”。

可能看起来很简单,但并不像看起来那么简单,请问我可以得到一些建议吗?

【问题讨论】:

  • 替换的重载之一允许您定义它应该覆盖的第一个和最后一个索引。 |您还可以扩展替换字符串以分别包含“观看”和“播放”。将搜索字符串扩展为填充内容是避免假阳性的常用方法。 |但总的来说,这属于语言科学和人工智能领域,而不是普通的编程领域。
  • 当替换字符串中的多个项目并希望确保您的替换是唯一的。所以下面会起作用: sentence.Replace("我在看"、"你在看").Replace("你在玩"、"我在玩")
  • 这是一个非常有趣的问题。使用代码,您可以引入第三个变量,但这是一个字符串。
  • 您可以获取每个替换位置的索引,然后对其进行子串化。

标签: c# regex string replace


【解决方案1】:

您可以利用 MatchEvaluator 作为 Regex.Replace 中的替换参数:

var sentence = "I was watching TV last night while she was reading a book and you were playing video games";
var result = Regex.Replace(sentence, @"\b(?:(I was)|you were)\b", m =>
    m.Groups[1].Success ? "you were" : "I was");
Console.WriteLine(result); 
// => you were watching TV last night while she was reading a book and I was playing video games

请参阅C# demo

在这里,\b(?:(I was)|you were)\b 匹配 I was(同时将匹配项捕获到第 1 组)或 you were 作为整个单词(\b 是单词边界)。如果m.Groups[1].Successtrue,则替换为you were,否则为I was

【讨论】:

  • 太棒了!一个简单而优雅的解决方案
【解决方案2】:

另一种解决方案是创建两个函数,一个替换第一次出现,第二个替换最后一次出现:

public static string ReplaceFirstOccurrence (string Source, string Find, string Replace)
{
    int Place = Source.IndexOf(Find);
    string result = Source.Remove(Place, Find.Length).Insert(Place, Replace);
    return result;
}

public static string ReplaceLastOccurrence(string Source, string Find, string Replace)
{
    int Place = Source.LastIndexOf(Find);
    string result = Source.Remove(Place, Find.Length).Insert(Place, Replace);
    return result;
}
ReplaceFirstOccurrence(sentence, "I was", "you were");
ReplaceLastOccurrence(sentence, "you were", "I was");

【讨论】:

    【解决方案3】:

    这是非常粗略的,对于大字符串来说会很慢,会分配很多内存,但它很容易解释并且可以完成工作。

    var input = "I was watching TV last night while she was reading a book and you were playing video games";
    
    var pairs = new [] { 
        (From: "I was", To: "you were"),
        (From: "you were", To:"I was")
        };
    
    var s = input;
    for(int i = 0; i < pairs.Length; i++) s = s.Replace(pairs[i].From, $"{{TOKEN{i}}}", ignoreCase: true, CultureInfo.InvariantCulture);
    for(int i = 0; i < pairs.Length; i++) s = s.Replace($"{{TOKEN{i}}}", pairs[i].To);
    
    Console.WriteLine(input);
    Console.WriteLine(s);
    s = char.ToUpper(s[0]) + s.Substring(1);
    Console.WriteLine(s);
    

    输出

    I was watching TV last night while she was reading a book and you were playing video games
    you were watching TV last night while she was reading a book and I was playing video games
    You were watching TV last night while she was reading a book and I was playing video games
    

    【讨论】:

      猜你喜欢
      • 2010-10-04
      • 2015-10-11
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-15
      相关资源
      最近更新 更多