简体   繁体   中英

How to replace in string without breaking ansi escape codes?

Instead of printing有色 , the following script prints 没有颜色 .

s = '1\x1b[1;31m2\x1b[0m3'
print(s)
s = s.replace('1', ' ')
print(s)

I understand that it is because the .replace operation has broken the ANSI escape codes. But this is unfortunate.

What's an easy way to make .replace , or str.translate , or re.sub safely ignore escape codes?

Using the regex to match ANSI escape sequences from an earlier answer, we can make a helper function that only replaces those parts of the text that do not belong to such a sequence.

Assuming this is utils.py :

import re

# https://stackoverflow.com/a/14693789/18771
ANSICODE = re.compile(r'\x1B[@-_][0-?]*[ -/]*[@-~]')

def replace_ansi(imput_str, search_str, replace_str):
    pos = 0
    result = []
    for m in ANSICODE.finditer(imput_str):
        text = imput_str[pos:m.start()]
        text = text.replace(search_str, replace_str)
        result.append(text)
        result.append(m.group())
        pos = m.end()

    text = imput_str[pos:]
    result.append(text)
    return ''.join(result)

usage

from utils import replace_ansi

s1 = 'bla 1\x1b[1;31mbla 2\x1b[0mbla 3'
s2 = replace_ansi(s1, '1', 'X')
print(s1)
print(s2)

prints

bla 1[1;31mbla 2[0mbla 3
bla X[1;31mbla 2[0mbla 3

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