0

When I receive input via C# it comes in escaping the \. When I'm trying to parse the string it causes an error because its using \\r instead of \r in the string. Is there some way to prevent it from escaping the \ or perhaps turning \\ into \ in the string. I've tried:

protected string UnEscape(string s)
{
    if (s == "")
        return " ";
    return s.Replace(@"\\", @"\");
}

With no luck. So any other suggestions.

EDIT:

I was not specific enough as some of you seemed confused as to what I'm trying to achieve. In debug I was reading "\\t" in a string but I wanted "\t" not because I want to output \t but because I want to output a [tab]. With the code above I was sort of trying to recreate something that has already been done through Regex.Unescape(string).

  • 3
    **What does the error say**? – SLaks Oct 25 '13 at 16:10
  • It's likely an issue with however you're accepting input. How *are* you accepting input? – Servy Oct 25 '13 at 16:10
  • 2
    How are you looking at the string value? – SLaks Oct 25 '13 at 16:10
  • Using textbox and there is no error it doesnt replace the \\ with \ it just tosses back out \\t. – user1938919 Oct 25 '13 at 16:11
  • your code will only replace any occurence of `\\` with a single `\` – Ahmad Oct 25 '13 at 16:11
  • 1
    possible duplicate of [Replace method c# not working as expected](http://stackoverflow.com/questions/15813454/replace-method-c-sharp-not-working-as-expected) - exactly the same until proven otherwise - looking at strings in debugger will show special characters escaped. – Alexei Levenkov Oct 25 '13 at 16:13
  • Are you sure that you're trying to unescape based on the string's value, not based on how it's encoded when you look at it in the debugger? – Tim S. Oct 25 '13 at 16:13
  • Im pretty sure its thinking of the \\ as a character which is why it wont replace string \\ with a single \. Its because the '\\' and 'r' are two chars but i want to make string "\\r" into '\r'. When its in a string. Is it possible. – user1938919 Oct 25 '13 at 16:15
  • The other question does not answer my question. Is there no way then to replace within a string "\\r" with a single character '\r' then? That is all I need to know. Im tring to create a general parser which will replace "text\\ttext" <- from debugger to "text\ttext" <- in debugger. – user1938919 Oct 25 '13 at 16:27
  • @user1938919: No. You're misunderstanding the debugger. (unless you want to turn the two characters `\` and `t` into an actual tab character) – SLaks Oct 25 '13 at 16:30

3 Answers3

3

The problem is that most .NET components do not process backslash escape sequences in strings: the compiler does it for them when the string is presented as a literal. However, there is another .NET component that processes escape sequences - the regex engine. You can use Regex.Unescape to do unescaping for you:

string escaped = @"Hello\thello\nWorld!";
string res = Regex.Unescape(escaped);
Console.WriteLine(res);

This prints

Hello   hello
World!

Note that the example uses a verbatim string, so \t and \n are not replaced by the compiler. The string escaped is presented to regex engine with single slashes, (although you would see double slashes if you look at the string in the debugger).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

The problem is not that it's escaping the backslash, it's that it's not parsing escape sequences into characters. Instead of getting the \r character when the characters \\ and r are entered, you get them as the two separate characters.

You can't turn @"\\" into @"\" in the string, because there isn't any double backslashes, that's only how the string is displayed when you look at it using debugging tools. It's actually a single backslash, and you can't turn that into the \ part of an escape sequence, because that's not a character by itself.

You need to replace any escape sequence in the input that you want to convert with the corresponding character:

s = s.Replace("\\r", "\r");

Edit:

To handle the special case that Servy is talking about, you replace all escape sequences at once. Example:

s = Regex.Replace(s, @"\\([\\rntb])", m => {
  switch (m.Groups[1].Value) {
    case "r": return "\r";
    case "n": return "\n";
    case "t": return "\t";
    case "b": return "\b";
    default: return "\\";
  }
});
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • This doesn't handle escaped escape characters. `"\\\\r"` should be `"\\r"`, not `"\\\r"`. – Servy Oct 25 '13 at 16:16
  • @Servy: What are you talking about? There is no such strings in the code. – Guffa Oct 25 '13 at 16:18
  • Right, I shouldn't have used string literals there. The point is an escaped \ character before a `r` shouldn't result in a translation to a carriage return, because the escape character is escaped. That...complicates the problem. – Servy Oct 25 '13 at 16:20
  • @Servy: Why do you think that? The OP is specifically asking for replacing the two characters `\\r` with the single character `\r`, and that is what the code does. – Guffa Oct 25 '13 at 16:29
  • 1
    The OP is looking to unescape a string literal. He gave an example using one escape sequence; that doesn't mean he doesn't expect any other escape sequences to be handled. – Servy Oct 25 '13 at 16:32
  • @Servy: What are you talking about? I gave an example on how to replace one escape sequence, that doesn't mean that it can't be done with other escape sequences. – Guffa Oct 25 '13 at 17:27
  • But *it does*, that's my point. It will work for the carriage return escape sequence, and the new line escape sequence, but not the case where the escape character is escaped. In that case these replaces don't ignore the double-escaped backslashes, resulting in incorrectly replacing in a special character. The first comment I posted shows an example. If you put in the input I showed you get the incorrect output as compared to a proper "unescape" method. – Servy Oct 25 '13 at 17:31
  • @Servy: Now I see what you mean. If you want to handle escaped backslashes, you do that exactly as any other escaped character, only you have to do that first. – Guffa Oct 25 '13 at 17:58
  • Nope, that wouldn't work. If you unescape it first you can't tell the difference between an actual escape character and an escaped escape character. You need to do it *last*, and ensure that the replaces ignore the double escaped escape characters. This is further complicated by triple/quadruple/etc. escape character. – Servy Oct 25 '13 at 18:01
  • @Servy: It's easier to replace all escape sequences at once. See my edit above. – Guffa Oct 25 '13 at 18:08
  • That would probably work, yes. I'm not confident enough in my regexes details to be entirely sure. – Servy Oct 25 '13 at 18:14
-1

If you have the three characters \, \, r in the input and you want to change this to the \r character then try

input.replace(@"\\r", "\r");

If you have the two characters \, r in the input and you want to change this to the \r character then try

input.replace(@"\r", "\r");
David Arno
  • 42,717
  • 16
  • 86
  • 131
  • This doesn't handle escaped escape characters. `"\\\\r"` should be `"\\r"`, not `"\\\r"`. – Servy Oct 25 '13 at 16:22
  • @Servy You seem to have a bit of a bee in your bonnet about `"\\\\r"` – David Arno Oct 25 '13 at 16:24
  • It's a particularly hard problem; one in which it seems several people didn't realize. Note that that's just one example that demonstrates an underlying flaw in the approach. You gave the same answer as two other people, your approach has the same flaw. I see no need to re-write another counter-example for the same approach. – Servy Oct 25 '13 at 16:26
  • @Servy, I disagree. It's a fairly simple problem. The challenge is merely in working out what the OP is actually asking for. – David Arno Oct 25 '13 at 16:28
  • It's simple if you use das's answer, because the regex engine then solves it for you. Writing it through pure string manipulation isn't so easy. Or, at the very least, your answer doesn't do it right. If you can provide a simple solution that handles escaped escape characters correctly then I'd love to see it. – Servy Oct 25 '13 at 16:29
  • @Servy Also, I gave slightly different answers to both Guffa and Sam I am. The devil is in the detail as they say... – David Arno Oct 25 '13 at 16:30
  • @Servy das' answer covers one possible interpretation of what the OP was asking for only. If that is what the OP wanted, then it's the perfect answer. If not, it's a no good answer. – David Arno Oct 25 '13 at 16:31