对字符串应用格式控制字符(退格符和回车符),而不需要递归

2024-04-27 02:36:47 发布

您现在位置:Python中文网/ 问答频道 /正文

“解释”字符串中格式化控制字符的最简单方法是什么,以便将结果显示为打印的结果。为了简单起见,我假设字符串中没有新行。

例如

>>> sys.stdout.write('foo\br')

显示for,因此

interpret('foo\br')应该是'for'

^{pr2}$

显示bar,因此

interpret('foo\rbar')应该是'bar'


我可以在这里编写正则表达式替换,但是,在'\b'替换的情况下,必须递归地应用它,直到不再出现。如果不使用递归,它将非常复杂。

有更简单的方法吗?


Tags: 方法字符串brforfoostdoutsysbar
3条回答

Python没有任何内置的或标准的库模块来实现这一点。 但是,如果您只关心简单的控制字符,如\r\b\n,则可以编写一个简单的函数来处理:

def interpret(text):
    lines = []
    current_line = []
    for char in text:
        if char == '\n':
            lines.append(''.join(current_line))
            current_line = []
        elif char == '\r':
            current_line.clear()
            # del current_line[:]  # in old python versions
        elif char == '\b':
            del current_line[-1:]
        else:
            current_line.append(char)
    if current_line:
        lines.append(current_line)
    return '\n'.join(lines)

您可以扩展函数来处理任何想要的控制字符。例如,您可能希望忽略一些在终端中没有实际显示的控制字符(例如,bell \a

如果效率无关紧要,那么简单的堆栈就可以了:

string = "foo\rbar\rbash\rboo\b\bba\br"

res = []
for char in string:
    if char == "\r":
        res.clear()
    elif char == "\b":
        if res: del res[-1]
    else:
        res.append(char)

"".join(res)
#>>> 'bbr'

否则,我认为在复杂的情况下,这是你所希望的最快速度:

^{pr2}$

请注意,我没有计时。在

更新:在询问了30分钟的说明和一个示例字符串之后,我们发现问题实际上完全不同:“如何对Python字符串重复应用格式化控制字符(backspace) 在这种情况下,显然需要反复应用regex/fn,直到停止获取匹配项。 解决方案:

import re

def repeated_re_sub(pattern, sub, s, flags=re.U):
    """Match-and-replace repeatedly until we run out of matches..."""
    patc = re.compile(pattern, flags)

    sold = ''
    while sold != s:
        sold = s
        print "patc=>%s<    sold=>%s<   s=>%s<" % (patc,sold,s)
        s = patc.sub(sub, sold)
        #print help(patc.sub)

    return s

print repeated_re_sub('[^\b]\b', '', 'abc\b\x08de\b\bfg')
#print repeated_re_sub('.\b', '', 'abcd\b\x08e\b\bfg')

[前面多次回答,要求澄清,并指出re.sub(...)或{}都可用于非递归地解决问题。]

相关问题 更多 >