3

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.

0

4 Answers 4

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for the detailed answer! sourceCode = sourceCode.replaceAll("\n", "\\\\n"); is what I was looking for.
I forgot to say, but System.lineSeparator() was one of the things I tried to solve the problem, without success, of course, because System.lineSeparator() returns \n on Linux. But firstly I used "\n".
3

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

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

1 Comment

Thank you for your answer. It also works. I prefer it, because it is simpler and less verbose.
3

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.

Comments

0

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");

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.