如何让 python 解释从文本文件读取的字符串中颜色的 ANSI 转义码

发布于 2025-01-12 19:03:25 字数 1510 浏览 1 评论 0原文

我尝试过的所有代码都可以在 VS Code 终端和 Widows 终端(Power 脚本和命令窗口)中工作,所以我对此感到非常高兴,但是,当我从文本文件读取字符串并打印该字符串时,转义码以普通视图打印,并且不对字符串应用任何颜色。

我尝试过八进制、十六进制和unicode版本,我对“\n”遇到了同样的问题,直到我意识到读取的字符串将包含“\n”,它会有效地转义“”字符,因此调用.replace字符串上的 ("\\n","\n") 解决了这个问题,但我对颜色代码没有任何兴趣。

这是我用来读取文件的代码:

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

ascii 文件中的示例:

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

使用 print 函数进行打印效果很好,无论是字符串常量还是来自变量

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)

想法?让我困惑的主要问题是代码没有解释/应用于我从文本文件中读取的字符串,其他任何东西似乎都有效。

更新:

正如评论中所建议的,该文件包含“\033”(4 个字符)而不是“\033”1 个字符。我希望 python 能够接受该行,然后在打印时将其应用/翻译/编码为 ANSI 转义序列代码,就像上面示例中的字符串一样。

与此同时,我设法使用一个脚本来获取文本文件中的颜色,该脚本用转义序列替换特定的字符串(我猜Python在将其写入文件之前会在幕后进行编码)

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)

这是一些进展,但不是什么我真的很想要。

回到我的问题,有没有办法读取文件并将序列 '\033' (4 个字符)解释为 1 字符转义序列,就像处理字符串一样?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

难理解 2025-01-19 19:03:25

有几种方法可以满足您的要求。

如果用引号将各个行括起来,使它们看起来像 Python 字符串常量,则可以使用 ast 文字计算器对其进行解码:

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

或者,您可以将字符串转换为字节字符串,并使用“unicode-escape”编解码器:

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

然而,以我的拙见,使用其他类型的标记来表示颜色会更好。我的意思是这样的:

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

也许不完全是 HTML 类型的语法,而是带有您理解的代码标记的东西,可以被人类阅读,并且可以被所有语言解释。

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.

何以畏孤独 2025-01-19 19:03:25

以二进制格式打开文件。然后按照蒂姆·罗伯茨的建议使用decode()。

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

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='' )
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文