2
$\begingroup$

Continuing from my previous question, this issue is an extension of it.

This issue is somewhat similar to how-do-i-make-a-string-literal-without-having-to-escape-backslashes? but not entirely the same, since I'm thinking of first storing a string in a variable and then declaring that it should be preserved as-is without escaping any escape characters encountered. I just give an example about graph6 strings from graph theory.

s = "ihChWC@?gE_@?@?A_@g?@??C??j?@l??E??Ao??\???m??@I??DF??E`O??GM??@?\
g??S\@o?@g@O??G?w??C?I??D?@o?@g?D???_?M??@??I??D??FK?E_?@Q??G??N??@???\
CPCOaG\a??"

I use the codes from the above link, but it still does not work.

$PreRead = (# /. 
         RowBox@{"RawString", "[", str_String, "]"} | 
           RowBox@{"RawString", "@", str_String} | 
           RowBox@{str_String, "//", "RawString"} :> 
          RowBox@{"StringTrim", "[", ToString@InputForm@str, ",", 
            "\"\\\"\"", "]"}) &;
    s1 = RawString@s
ImportString[s1, "Graph6"]

The code above seems to require the string immediately following RawString, rather than storing the string in a variable. What should I do in this case?

    s1 = RawString@
      "ihChWC@?gE_@?@?A_@g?@??C??j?@l??E??Ao??\???m??@I??DF??E`O??GM??@?\
    g??S\@o?@g@O??G?w??C?I??D?@o?@g?D???_?M??@??I??D??FK?E_?@Q??G??N??@???\
    CPCOaG\a??"
    ImportString[s1, "Graph6"]

I tried to replace the character \ with \\, but it still failed.

s = "ihChWC@?gE_@?@?A_@g?@??C??j?@l??E??Ao??\???m??@I??DF??E`O??GM??@?\
g??S\@o?@g@O??G?w??C?I??D?@o?@g?D???_?M??@??I??D??FK?E_?@Q??G??N??@???\
CPCOaG\a??";
s1 = StringReplace[s, "\\" -> "\\\\"];
ImportString[s1, "Graph6"]

Import::fmterr: Cannot import data as Graph6 format.

I know that in Python, one way to do it is as follows:


import networkx  as nx
escape_dict={'\a':r'\a',
             '\b':r'\b',
             '\c':r'\c',
             '\f':r'\f',
             '\n':r'\n',
             '\r':r'\r',
             '\t':r'\t',
             '\v':r'\v',
             '\'':r'\'',
             '\"':r'\"'}

def raw(text):
    """Returns a raw string representation of text"""
    new_string=''
    for char in text:
        try: 
            new_string += escape_dict[char]
        except KeyError: 
            new_string += char
    return new_string

line = 'ihChWC@?gE_@?@?A_@g?@??C??j?@l??E??Ao??\???m??@I??DF??E`O??GM??@?g??S\@o?@g@O??G?w??C?I??D?@o?@g?D???_?M??@??I??D??FK?E_?@Q??G??N??@???CPCOaG\a??'
line=raw(line)
G = nx.from_graph6_bytes(line.encode())
print(G)

See also how-to-prevent-automatic-escaping-of-special-characters-in-python.

Can Mathematica handle it in a similar way?

$\endgroup$

2 Answers 2

2
$\begingroup$

There seems to be a bit of a misunderstanding here. A string itself is not escaped or unescaped. A string is just a list of characters.

The issue is with how you transfer these strings between various programs on your computer. In both Mathematica and Python, a string containing a single backslash is written as "\\". There is one character in this:

In[30]:= StringLength["\\"]
Out[30]= 1

In[31]:= ToCharacterCode["\\"]
Out[31]= {92}

But we had to enter it in a special way. It's only an issue of notation.

This special notation means that if you have a text file containing Graph6 code, and you open it with a text editor, you cannot simply copy and paste into a Mathematica notebook or a Python source file. You need to edit all characters that require special notation. For example, if the file contains I]zn\}~nw, you must enter it as I]zn\\}~nw in Mathematica.

Therefore, convenient options are:

Just Import the file instead of copying and pasting.

Or use the notebook where where Mathematica offers to auto-escape for you when pasting into a string. Enter "", position the cursor between the quotes, then paste.

enter image description here

I hit Yes and I get:

enter image description here

Never paste first, quote later. The chance of mistakes is too great. Enter quotes first, paste after, and let Mathematica escape for you automatically.

$\endgroup$
5
  • $\begingroup$ Sometimes strings come from other programs, such as geng, transmission pipelines rather than files, such as your code in the link mathematica.stackexchange.com/a/211292/67902. I am a bit worried that ImportString in your codes may cause the same problem. $\endgroup$
    – licheng
    Commented Sep 30, 2023 at 15:56
  • $\begingroup$ If the number of strings is small or reading files, your method is nice. But I'm a bit worried about this pipeline transmission. $\endgroup$
    – licheng
    Commented Sep 30, 2023 at 15:59
  • 1
    $\begingroup$ I was simply trying to point out that the issue is with the way you enter strings into Mathematica. The two methods I present here (use a file, or paste inbetween quotes and let Mathematica do the escaping) are both robust. What you are trying to do is not. The answer you accepted is simply wrong, beware of trying to do that. $\endgroup$
    – Szabolcs
    Commented Sep 30, 2023 at 16:25
  • $\begingroup$ I'm temporarily holding off on accepting answers because I don't understand it yet. What I mean is that the string we get may not be copied manually, but passed from other places, such as shell. In this case, I may pay attention to the problem that needs to be escaped. So I have to first import the string into a variable and then declare it without escaping. Maybe these worries are unnecessary. $\endgroup$
    – licheng
    Commented Oct 1, 2023 at 1:02
  • $\begingroup$ This kind of import is not something I can copy and paste, unless Mathematica can handle it itself. I think I need to reopen a pipe transmission issue. $\endgroup$
    – licheng
    Commented Oct 1, 2023 at 1:11
-1
$\begingroup$

At least for this particular case, using the UTF8 CharacterEncoding allows you to import the string as "Graph6":

s = "ihChWC@?gE_@?@?A_@g?@??C??j?@l??E??Ao??\???m??@I??DF??E`O??GM??@?\
g??S\@o?@g@O??G?w??C?I??D?@o?@g?D???_?M??@??I??D??FK?E_?@Q??G??N??@???\
CPCOaG\a??"

sUTF8 = ToString[s, CharacterEncoding -> "UTF8"]
g = ImportString[sUTF8, "Graph6"]
(* Output*)

enter image description here

$\endgroup$
10
  • $\begingroup$ That's pretty amazing! I tried doing it in Python too (print(line.encode("utf-8"))), but it didn't work out. I'm not sure what kind of magic Mathematica used. $\endgroup$
    – licheng
    Commented Sep 30, 2023 at 9:06
  • 1
    $\begingroup$ No magic actually. If we consider s being a raw string(backslashes are to be interpreted as a literal), the same is valid in python line = r'ihC..\@..' G = nx.from_graph6_bytes(line.encode("UTF-8")) . Using the UTF8 Encoding is actually intended to simulate the same behaviour in MMA by reading the string one byte at a time (of course there are definitely better ways to do it). Having a closer look at ToString["\@", CharacterEncoding -> #] & /@ {"Unicode", "UTF8"} // {# -> StringLength@#} & /@ # &; (* {{"\@" -> 1}, {"\\@" -> 2}}*) one can see the difference in applying different encodings $\endgroup$
    – vindobona
    Commented Sep 30, 2023 at 13:59
  • $\begingroup$ This is not correct, and attempting to do this will lead to errors. The issue has to do with escape sequences and not UTF8. $\endgroup$
    – Szabolcs
    Commented Sep 30, 2023 at 16:18
  • $\begingroup$ @Szabolcs But in my Mathematica 13.3, it is well. What happened? Is it because of the version? $\endgroup$
    – licheng
    Commented Sep 30, 2023 at 16:28
  • $\begingroup$ It is not well. Try GCf\tw. There is not such thing as an "unescaped string" and "escaped string". A string can contain any sequence of characters, but when you write it as Mathematica code, you need to use the correct notation (i.e. escaping). The problem you see if not with the string, but the way you are trying to enter that string. $\endgroup$
    – Szabolcs
    Commented Sep 30, 2023 at 16:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.