Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java - Replace new line character by \n

Tags:

java

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.

like image 492
Antônio Medeiros Avatar asked Jun 07 '26 17:06

Antônio Medeiros


2 Answers

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.

like image 119
davidxxx Avatar answered Jun 10 '26 06:06

davidxxx


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

sourceCode = sourceCode.replace("\n", "\\n");
like image 25
khelwood Avatar answered Jun 10 '26 05:06

khelwood