簡體   English   中英

Python的regex,ascii轉義符到標簽

[英]Python's regex, ascii escape character to tags

我有以下Xterm的輸出:

text = '\x1b[0m\x1b[01;32mattr\x1b[0m\n\x1b[01;36mawk\x1b[0m\n\x1b[01;32mbasename\x1b[0m\n\x1b[01;32mbash\n\x1b[0many text'

我知道\\x1b[0m將刪除所有文本屬性,而\\x1b[01將刪除粗體文本, \\x1b[32m是綠色文本, \\x1b[01;32m是粗體綠色文本。 那么如何將這些轉義字符傳遞給我自己的標簽呢? 像這樣:

\x1b[0m\x1b[01;32mattr --> <bold><green>attr</bold></green>

我希望我的text變量變為:

text = '<bold><green>attr</bold></green>\n<bold><cyan>awk</bold></cyan>\n<bold><green>basename</bold></green>\n<bold><green>bash</bold></green>\nanytext'
import re

text = '\x1b[0m\x1b[01;32mattr\x1b[0m\n\x1b[01;36mawk\x1b[0m\n\x1b[01;32mbasename\x1b[0m\n\x1b[01;32mbash\n\x1b[0many text'

# dictionary mapping text attributes to tag names
fmt = {'01':'bold', '32m':'green', '36m': 'cyan'}
# regex that gets all text attributes, the text and any potential newline
groups = re.findall('(\n?)\\x1b\[((?:(?:0m|32m|01|36m);?)+)([a-zA-Z ]+)', text)
# iterate through the groups and build your new string
xml = []
for group in groups:
    g_text = group[2] # the text itself
    for tag in group[1].split(';'): # the text attributes 
        if tag in fmt:
            tag = fmt[tag]
        else:
            continue
        g_text = '<%s>%s</%s>' %(tag,g_text,tag)
    g_text = group[0] + g_text # add a newline if necessary
    xml.append(g_text)
xml_text = ''.join(xml)

print(xml_text)

<green><bold>attr</bold></green>
<cyan><bold>awk</bold></cyan>
<green><bold>basename</bold></green>
<green><bold>bash</bold></green>
any text

有關正則表達式的演示,請參見以下鏈接: Debuggex演示

當前,正則表達式假定您在實際文本中僅包含字母字符或空格,但可以隨時在正則表達式末尾更改此組([a-zA-Z ]+) ,以包括文本中可能包含的其他字符。

另外,我假設您具有比粗體,綠色和青色更多的文本屬性。 您將需要使用其他屬性及其映射來更新fmt字典。

編輯

@caaarlos'已在注釋中(如下)要求將ansi代碼保持在輸出中,如果它未出現在fmt詞典中:

import re

text = '\x1b[0m\x1b[01;32;35mattr\x1b[0;7m\n\x1b[01;36mawk\x1b[0m\n\x1b[01;32;47mbasename\x1b[0m\n\x1b[01;32mbash\n\x1b[0many text'

fmt = {'01':'bold', '32':'green', '36': 'cyan'}

xml = []
active_tags = []
for group in re.split('\x1b\[', text):
    if group.strip():
        codes, text = re.split('((?:\d+;?)+)m', group)[1:]
        not_found = []
        for tag in codes.split(';'):
            if tag in fmt:
                tag = fmt[tag]
                text = '<%s>%s' %(tag,text)
                active_tags.append(tag)
            elif tag == '0':
                for a_tag in active_tags[::-1]:
                    text = '</%s>%s' %(a_tag,text)
                active_tags = []
            else:
                not_found.append(tag)
        if not_found:
            text = '\x1b[%sm%s' %(';'.join(not_found), text)
        xml.append(text)
xml_text = ''.join(xml)

print(repr(xml_text))

'\x1b[35m<green><bold>attr\x1b[7m</bold></green>\n<cyan><bold>awk</bold></cyan>\n\x1b[47m<green><bold>basename</bold></green>\n<green><bold>bash\n</bold></green>any text'

請注意,上面編輯的代碼還可以處理標簽未在文本后立即關閉的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM