Jebathon
Jebathon

Reputation: 4581

Java - Properly format a String given escape sequences and escape characters

Given new line (\n), tab (\t) and an escape character \ how can I given a string format it properly so it deals with these escape sequences and escape characters properly. Example 1:

"string \\t \t"

The output would be:

"string \t    "

So in this case \\t is escaped to just \t and \t is formatted with a tab

Example 2:

"string \\t \n \\n"

The output is:

"string \t
\n"

I tried brute-forcing a solution but it didn't work as I am having problems delimiting tabs and spaces with a backslash infront.

String v= "..." //v for value
v = v.replace("\\\"","\"");
v = v.replace("\\\\","\\");
v = v.replace("\\t", "  ");
v = v.replace("\\n", "\n");
v = v.replace("\\\t", "\\t");
v = v.replace("\\\n", "\\n");

If I ran that code through the first example it would give:

"string         "

Upvotes: 0

Views: 2734

Answers (2)

flakes
flakes

Reputation: 23674

You can first is replace escaped symbols and then replace escaped slashes with single slashes:

[\, \, \, n] -> [\, \, \n] -> [\, \n]

We can do this by finding occurrences of two slash pairs:

(^|[^\\])(\\\\)*

- (^|[^\\]) is the start of the string or not a slash
- (\\\\)* is slash pairs

Combine this with the symbol you want to replace (for example \n):

((^|[^\\])(\\\\)*)(\\n)

Then we escape this string for java:

((^|[^\\\\])(\\\\\\\\)*)(\\\\n)

Now you can write a helper method for this regex which keeps the first group $1 and replaces the second group:

public static String replaceEscapedChar(
    final String source, 
    final char escaped, 
    final char actual
) {
    final String replacee = "(\\\\" + escaped + ")";
    final String replacement = "$1" + actual;
    return source.replaceAll("((^|[^\\\\])(\\\\\\\\)*)" + replacee, replacement); 
}

For example. The following produces:

replaceEscapedChar("Test\\\\\\nTest\\\\n", 'n', '\n');

Test\\
Test\\n

PS: You can also remove the quotes afterwards by writing:

source.replaceAll("((\\\\\\\\)+)", "\\\\");

Upvotes: 1

jamey graham
jamey graham

Reputation: 1204

looks like the one "brute force" combination you didn't try is correct

replace("\\t", "\t")

reading "replace all < backslash >< t > combinations with < tab >"

String them all together to get

v = v.replace("\\t", "\t").replace("\\n", "\n")

(there's no need to replace \ by itself)

Upvotes: 1

Related Questions