4

do you have any ideas or tips how to replace a string safely?

Example:

string Example = "OK OR LOK";

Now i want to replace "OK" with true and "LOK" with false.

Example = Example.Replace("OK", "true");
Example = Example.Replace("LOK", "false");

Now the Result is: Example = "true or Ltrue";

The Result should be: Example ="true or false";

I understand the problem, but i have no idea how to fix this.

Thanks

Mong Zhu
  • 23,309
  • 10
  • 44
  • 76
Gerry Seel
  • 63
  • 7

4 Answers4

6

You could replace the longest strings first, f.e. with this method:

public static string ReplaceSafe(string str, IEnumerable<KeyValuePair<string, string>>  replaceAllOfThis)
{
    foreach (var kv in replaceAllOfThis.OrderByDescending(kv => kv.Key.Length))
    {
        str = str.Replace(kv.Key, kv.Value);
    }
    return str;
}

Your example:

Example = ReplaceSafe(Example, new[] {new KeyValuePair<string, string>("OK", "true"), new KeyValuePair<string, string>("LOK", "false")});
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
4
Example = Example.Replace("LOK", "false").Replace("OK", "true");
Rai Vu
  • 1,595
  • 1
  • 20
  • 30
3

You could look for "LOK" first, but that won't help with the more general problem of not matching "POKE" and producing "PtrueE", and so on.

The following looks for word boundaries:

new Regex(@"\bLOK\b").Replace(
  new Regex(@"\bOK\b").Replace("OK OR LOK", "true"),
  "false")

A more flexible approach again is to both look for word boundaries and to identify which replacement one is doing in a match-evaluator:

new Regex(@"\bLOK|OK\b").Replace("OK OR LoK", m =>
{
  switch(m.Value)
  {
    case "OK":
      return "true";
    default:
      return "false";
  }
})

This is the approach least likely to run into further conflicts between different search keys.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
  • okay works fine but if i want to do this, nothing happend: string OK = "OK"; string replace = new Regex(@"\b" + OK + "\b").Replace(Example, "true"); – Gerry Seel Dec 08 '16 at 10:55
  • Your second `"\b"` is the code for the backspace character, it should be `@"\b"` or `"\\b"`. As well as that if you're constructing dynamcally you should use `@"\b" + Regex.Escape(OK) + @"\b"` so that way if your search string (`OK`) contains any characters that are special in regular expressions they're escaped to match the actual character. – Jon Hanna Dec 08 '16 at 11:03
1

This might be an overhead for such a problem, but here is a version using RegEx with a negative lookbehind:

string Example = "OK OR LOK";
// Replace "OK" which is not preceded by any word character
string res = Regex.Replace(Example, @"(?<!\w)OK", "true");
string res2 = Regex.Replace(res, @"(?<!\w)LOK", "false");

Console.WriteLine(res);
Console.WriteLine(res2);

EDIT: inspired by @Jon Hanna.

if the OK or LOK should have a tail like OKE or LOCKS a positive looakhead for space (\s) or end of string ($) could solve the problem:

string res = Regex.Replace(Example, @"(?<!\w)OK(?=[\s|$])", "true");
string res2 = Regex.Replace(res, @"(?<!\w)LOK(?=[\s|$])", "false");
Mong Zhu
  • 23,309
  • 10
  • 44
  • 76