Reputation: 122012
In Python, I can do string replacements of slashes as such:
>>> s = 'ab\c'
>>> s.replace('\\', '\\\\')
'ab\\\\c'
>>> print s.replace('\\', '\\\\')
ab\\c
In Julia, when I could do this:
julia> s = "ab\\c"
"ab\\c"
julia> replace(s, "\\\\", "\\\\\\\\")
"ab\\c"
I've tried this but it throws some syntax error:
julia> replace(s, r"\", r"\\")
ERROR: syntax: "\" is not a unary operator
Upvotes: 2
Views: 1742
Reputation: 33249
There are two sources of confusion here, one of which is the printing vs. REPL output issue that Dan mentions. The root cause of confusion, however, seems to be that string literals have different escaping behavior in Julia and Python:
In Julia, a \
inside of a string literal always escapes the next character – a single backslash never produces a literal backslash, it always combines with the following characters. If the following character has no special meaning as an escape, then the following character is produced by itself and no backslash is in the resulting string. This is the case here: there is no special meaning to escapes beginning with c
so "ab\c"
is the same as just "abc"
.
In Python, a \
inside of a string literal sometimes escapes the next character, but if the following character has no special meaning, then it does not introduce an escape so the sequence produces a literal backslash as well as whatever follows. In this case, 'ab\c'
or "ab\c"
are both equal to "ab\\c"
(the second backslash is escaped by the first backslash, producing a single literal backslash).
Note that the two backslash form is how the Python prompt prints the string back to you – this is the standard way to write this string, properly escaped, instead of relying on the fact that c
has no special meaning as an escape character. If the backslash were instead followed by some other character with special meaning as an escape (see examples below), then the input string would mean something else entirely.
Here some examples in Python:
>>> [c for c in "ab\c"]
['a', 'b', '\\', 'c']
>>> [c for c in "ab\\c"]
['a', 'b', '\\', 'c']
>>> [c for c in "a\bc"]
['a', '\x08', 'c']
>>> [c for c in "a\\bc"]
['a', '\\', 'b', 'c']
>>> [c for c in "\abc"]
['\x07', 'b', 'c']
>>> [c for c in "\\abc"]
['\\', 'a', 'b', 'c']
Here are the analogous examples in Julia:
julia> [c for c in "ab\c"]
3-element Array{Char,1}:
'a'
'b'
'c'
julia> [c for c in "ab\\c"]
4-element Array{Char,1}:
'a'
'b'
'\\'
'c'
julia> [c for c in "a\bc"]
3-element Array{Char,1}:
'a'
'\b'
'c'
julia> [c for c in "a\\bc"]
4-element Array{Char,1}:
'a'
'\\'
'b'
'c'
julia> [c for c in "\abc"]
3-element Array{Char,1}:
'\a'
'b'
'c'
julia> [c for c in "\\abc"]
4-element Array{Char,1}:
'\\'
'a'
'b'
'c'
The escapes \a
and \b
have special meaning in both languages – they encode the ASCII "bell" and "backspace" characters in each language. The difference lies in the sequence \c
: in Julia this encodes just the character c
whereas in Python it encodes two characters – backslash and c
– because c
happens not to have a special meaning as an escape. Julia's string escaping rules closely resemble C, C++, Java, Perl and Ruby and were derived from them. I'm not sure what the provenance of Python's string escaping behavior is.
Update: Invalid escapes in string literals will be syntax errors in future versions of both Julia (issue #21284) and Python (3.6 release notes). This brings Julia and Python's behaviors for escaping of string literals into agreement.
Upvotes: 4
Reputation: 18217
Julia REPL outputs strings in escaped form. It might be best to wrap things with a println
as in println(replace(s, "\\", "\\\\"))
. In this case you get:
julia> s = "ab\\c"
"ab\\c"
julia> println(s)
ab\c
julia> println(replace(s, "\\", "\\\\"))
ab\\c
Regarding the use of regular expressions, the first r"\"
is a partial regular expression and the parser continue and generates an error on the following \
after a closing "
, and the second regexp is unnecessary as it is the string to be inserted.
UPDATE: More details about Julia vs. Python escaping in the other answer.
Hope this helps!
Upvotes: 5