简体   繁体   中英

How do I get python to interpret the ANSI escape codes for colors in a string read from a text file

All the codes I've tried work in VS Code terminal and the Widows Terminal (Power Script and Command Window), so I'm pretty happy about that, however, when I read a string from a text file and I print the string, the escape codes are printed in plain view and no colour is applied to the strings.

I've tried the octal, hexadecimal and unicode versions, I had the same problem with "\n" until I realised that the string read would contain "\n", where it would effectively escape the "" char, so calling.replace("\\n","\n") on the string solved that issue, but I got no joy with the colour codes.

This is the code that I use to read the file:

with open('ascii_art_with_color.txt','r') as file: 
    for line in file.readlines() :
        text_line = line
        print( text_line , end='' )

Sample from the ascii file:

encounter = You \033[31mencounter\033[0m a wolf howling at the moonlight

Printing using the print function works just fine, either the string constant or from a variable

print('The wolf \033[31mgrowls\033[0m at you as you try to get closer')

winning = 'The wolf lets out a \033[34mpiercing\033[0m cry, then falls to the ground'
print(winning)

Ideas? The main problem that got me stumped is that the codes are not interpreted/applied for the strings I read from the text file, anything else seems to work.

Update:

As it was suggested in the comments, the file contained the '\033' (4 chars) instead of the '\033' one char. I was hoping python would take the line, then apply/translate/encode it into the ANSI escape sequence code while printing it, as it does with the string in the example above.

In the meantime, I managed to get the colours in the text file using a script that replaces a specific string with the escape sequence (I guess python does the encoding behind the scenes before writing it to file)

file_dest = 'ascii_monster_wolf_dest.txt'
with open(file_name,'r') as file, open(file_dest,'w+') as file_dest:
    for line in file.readlines():
        line = line.replace('{@}','\033[31m')
        line = line.replace('{*}','\033[0m')
        file_dest.writelines(line)

This is some progress, but not what I really wanted tho.

Coming back to my question, is there a way to read the file and have the sequence '\033' (4 characters) being interpreted as the 1 char escape sequence, the way it seems to do with strings?

There are a couple of ways to do what you ask.

If you wrap the individual lines with quote marks, so they look like Python string constants, you can use the ast literal evaluator to decode it:

s = '"\\x61\\x62"'
# That string has 10 characters.
print( ast.literal_eval(s) )
# Prints  ab

Alternatively, you can convert the strings to byte strings, and use the "unicode-escape" codec:

s = '\\x61\\x62'
s = s.encode('utf-8').decode('unicode-escape')
print( s )
# Prints   ab

In my humble opinion, however, you would be better served by using some other kind of markup to denote your colors. By that, I mean something like:

<red>This is red</red>  <blue>This is blue</blue

Maybe not exactly an HTML-type syntax, but something with code markers that YOU understand, that can be read by humans, and can be interpreted by all languages.

Open the file in binary format. Then use decode() as Tim Roberts suggested.

with open('ascii_art_with_color.txt','rb') as file: 
    for line in file.readlines() :
        print( line.decode('unicode-escape') , end='' )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM