我有成千上万行的python代码有python2.7 +样式字符串格式化(例如{} s中没有索引)
"{} {}".format('foo', 'bar')
我需要在python2.6下运行此代码,而python2.6 需要索引。
我想知道是否有人知道一种无痛的方式允许python2.6运行此代码。如果有一个“来自__future__ import blah”解决问题,那就太棒了。我没有看到一个。这些方面的东西将是我的第一选择。
遥远的第二个是可以自动化添加索引的过程的脚本,至少在明显的情况下是这样的:
"{0} {1}".format('foo', 'bar')
答案 0 :(得分:6)
它并没有完全保留whitespacing并且可能会变得更聪明,但它至少会正确识别Python字符串(撇号/引号/多行),而无需使用正则表达式或外部解析器:
import tokenize
from itertools import count
import re
with open('your_file') as fin:
output = []
tokens = tokenize.generate_tokens(fin.readline)
for num, val in (token[:2] for token in tokens):
if num == tokenize.STRING:
val = re.sub('{}', lambda L, c=count(): '{{{0}}}'.format(next(c)), val)
output.append((num, val))
print tokenize.untokenize(output) # write to file instead...
示例输入:
s = "{} {}".format('foo', 'bar')
if something:
do_something('{} {} {}'.format(1, 2, 3))
示例输出(稍微注意一下whitespacing):
s ="{0} {1}".format ('foo','bar')
if something :
do_something ('{0} {1} {2}'.format (1 ,2 ,3 ))
答案 1 :(得分:0)
您可以定义一个函数来重新格式化格式字符串:
def reformat(s):
return "".join("".join((x, str(i), "}"))
for i, x in list(enumerate(s.split("}")))[:-1])
答案 2 :(得分:0)
也许是一个很好的旧sed-regex,如:
sed source.py -e 's/{}/%s/g; s/\.format(/ % (/'
您的示例将更改为:
"%s %s" % ('foo', 'bar')
当然,你放弃了花哨的新风格.format()
,但对于微不足道的价值插入几乎没有用。
答案 3 :(得分:0)
转换脚本可能非常简单。您可以找到要用正则表达式替换的字符串:
fmt = "['\"][^'\"]*{}.*?['\"]\.format"
str1 = "x; '{} {}'.format(['foo', 'bar'])"
str2 = "This is a function; 'First is {}, second is {}'.format(['x1', 'x2']); some more code"
str3 = 'This doesn't have anything but a format. format(x)'
str4 = "This has an old-style format; '{0} {1}'.format(['some', 'list'])"
str5 = "'{0}'.format(1); '{} {}'.format(['x', 'y'])"
def add_format_indices(instr):
text = instr.group(0)
i = 0
while '{}' in text:
text = text.replace('{}', '{%d}'%i, 1)
i = i+1
return text
def reformat_text(text):
return re.sub(fmt, add_format_indices, text)
reformat_text(str1)
"x; '{0} {1}'.format(['foo', 'bar'])"
reformat_text(str2)
"This is a function; 'First is {0}, second is {1}'.format(['x1', 'x2']); some more code"
reformat_text(str3)
"This doesn't have anything but a format. format(x)"
reformat_text(str4)
"This has an old-style format; '{0} {1}'.format(['some', 'list'])"
reformat_text(str5)
"'{0}'.format(1); '{0} {1}'.format(['x', 'y'])"
我认为你可以通过这个扔掉一个完整的文件。您可以找到更快的add_format_indices实现,显然它还没有经过大量的测试。
太糟糕了,没有import __past__
,但一般来说这不是通常提供的东西(例子见2to3脚本),所以这可能是你的下一个最佳选择。