Antonio Medeiros
Antonio Medeiros

Reputation: 3268

java - Replace new line character by \n

I'm coding an IDE. Let's say I have the Hello, World Pascal program on a string:

String sourceCode = "program Hello;\nbegin\nwriteln ('Hello, world.');\nend.";

If I do System.out.println(sourceCode); the output shows:

program Hello;
begin
writeln ('Hello, world.');
end.

Great, but I want to show new lines as \n. I tried:

sourceCode = sourceCode.replaceAll(System.lineSeparator(), "\\n");

But then System.out.println(sourceCode); outputs:

program Hello;nbeginnwriteln ('Hello, world.');nend.

When I expected \n to be shown:

program Hello;\nbegin\nwriteln ('Hello, world.');\nend.

How can I achieve that? Full demo:

public class PrintPascalHelloWorld {
    public static void main(String[] args) {
        String sourceCode = "program Hello;\nbegin\nwriteln ('Hello, world.');\nend.";
        System.out.println(sourceCode);
        sourceCode = sourceCode.replaceAll(System.lineSeparator(), "\\n");
        System.out.println(sourceCode);
    }
}

I'm able to compile and run it using Online Java IDE.

Upvotes: 3

Views: 307

Answers (4)

davidxxx
davidxxx

Reputation: 131546

You use String.replaceAll(String regex, String replacement) that takes as first parameter a String regex and as second one a String replacement.
This method has some specificities about the replacement String. Especially, if it contains a \ or a $ , it may not be interpreted as a literal.

According to the Matcher.replaceAll() specified used under the hood by String.replaceAll() :

Note that backslashes () and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string. Dollar signs may be treated as references to captured subsequences as described above, and backslashes are used to escape literal characters in the replacement string.

In your case, sourceCode.replaceAll(System.lineSeparator(), "\\n") will escape the literal n character.

If you want to use replaceAll(), you should use a convoluted way such as :

sourceCode = sourceCode.replaceAll("\n", "\\\\n");

As you don't need to work with a regex, it makes more sense to use String.replace(CharSequence target, CharSequence replacement) that replaces a CharSequence by another and String is an instance of CharSequence.
So you can invoke :

sourceCode = sourceCode.replace("\n", "\\n")

where now the String replacement is handled as a literal.


Note also that System.lineSeparator() makes sense as you write in a file outputstream where the new line characters are inevitably OS dependent.
The \n end-of-line contained in a String such as "program Hello;\nbegin\nwriteln ('Hello, world.');\nend."; is not OS dependent.

For example on Windows, a JVM 8 handles indifferently the Windows new line characters (\r\n) and \n as you print them in the standard output.

This code on Windows :

String sourceCode = "program Hello;\r\nbegin\nwriteln ('Hello, world.');\r\nend.";
System.out.println(sourceCode);

produces indeed :

program Hello;

begin

writeln ('Hello, world.');

end.

Upvotes: 4

Harshal Khachane
Harshal Khachane

Reputation: 266

If you are testing the code on windows machine then it will surely fail. As

System.lineSeparator()

will return "\r\n" on windows. And it will not match "\n" from your input string.

You need to change to below code

sourceCode = sourceCode.replaceAll("\n", "\\\\n");

Upvotes: 0

khelwood
khelwood

Reputation: 59228

You don't need to use replaceAll unless you are trying to use regular expressions. replace works fine.

sourceCode = sourceCode.replace("\n", "\\n");

Upvotes: 3

Karol Dowbecki
Karol Dowbecki

Reputation: 44980

Since System.lineSeparator() is platform dependent, as per docs:

On UNIX systems, it returns "\n"; on Microsoft Windows systems it returns "\r\n".

It will be better to use \n directly:

String sourceCode = "program Hello;\nbegin\nwriteln ('Hello, world.');\nend.";
System.out.println(sourceCode);
sourceCode = sourceCode.replaceAll("\n", "\\\\n");
System.out.println(sourceCode);

is going to display:

program Hello;
begin
writeln ('Hello, world.');
end.
program Hello;\nbegin\nwriteln ('Hello, world.');\nend.

Upvotes: 3

Related Questions