在字符串中“解释”格式控制字符的最简单方法是什么,以便将结果显示为打印结果。为简单起见,我假设字符串中没有换行符。
例如,
>>> sys.stdout.write('foo\br')
显示for
,因此
interpret('foo\br')
应为'for'
>>>sys.sdtout.write('foo\rbar')
显示bar
,因此
interpret('foo\rbar')
应为'bar'
我可以在这里写一个正则表达式替换,但是,在'\b'
替换的情况下,它必须递归地应用,直到不再出现。如果没有递归就完成了。
有更简单的方法吗?
答案 0 :(得分:1)
如果效率无关紧要,一个简单的堆栈就可以正常工作:
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'
否则,我认为在复杂的情况下,这个速度和你希望的一样快:
string = "foo\rbar\rbash\rboo\b\bba\br"
try:
string = string[string.rindex("\r")+1:]
except ValueError:
pass
split_iter = iter(string.split("\b"))
res = list(next(split_iter, ''))
for part in split_iter:
if res: del res[-1]
res.extend(part)
"".join(res)
#>>> 'bbr'
请注意,我还没有计时。
答案 1 :(得分:1)
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)
您可以扩展处理所需控制字符的功能。例如,您可能想要忽略一些未在终端中实际显示的控制字符(例如,响铃\a
)
答案 2 :(得分:0)
更新:在要求澄清和示例字符串30分钟后,我们发现问题实际上完全不同:"如何 重复应用格式控制字符(退格) 到Python字符串?" 在这种情况下,你显然需要反复应用正则表达式/ 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(...)
或string.replace(...)
都可用于解决问题,非递归。]