Reputation: 3268
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
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
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
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
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