从旧样式自动转换高级字符串格式化程序

时间:2013-12-30 22:18:36

标签: python string string-formatting

有没有自动方法将一段代码从python的旧样式字符串格式(使用%)转换为新样式(使用.format)?例如,考虑formatting of a PDB atom specification

spec = "%-6s%5d %4s%1s%3s %1s%4d%1s   %8.3f%8.3f%8.3f%6.2f%6.2f          %2s%2s"

我已根据需要手动转换其中一些规格,但由于我有许多这样的规格,这既容易出错又耗时。

3 个答案:

答案 0 :(得分:4)

两种表单的功能完全不匹配,因此您无法将每个%字符串自动转换为等效的{}字符串或(尤其)反之亦然。

当然有很多重叠,两种格式语言的许多子部分是相同或非常相似的,所以某人可以编写一个部分转换器(可以,例如, ,为不可兑换代码提出异常)。

对于您似乎正在使用的语言的一小部分,您可以使用简单的正则表达式轻松完成 - 每个模式都以%开头,并以[sdf]之一结束,并且像{:\1\2}这样的替代模式应该是你所需要的。

但为什么要这么麻烦?除了作为编写解析器的练习外,还有什么好处?不推荐使用%运算符,并且使用%现有%格式字符串显然至少与使用format格式的%一样好字符串转换为{}

如果你视为编写解析器的练习,我相信pyparsing内部有一个不完整的例子。


一些难以翻译的差异,在我的头脑中:

  • *用于动态字段宽度或精度; format具有相似的功能,但却有所不同。
  • %(10)s,因为format尝试先将密钥名称解释为数字,然后再回到dict密钥。
  • %(a[b])s,因为format没有引用或以其他方式将密钥与字段的其余部分分开,因此无法使用各种字符。
  • %c采用整数或单字符串; :c只有整数。
  • %r / %s / %a类似物不是格式字符串的一部分,而是字段的一部分(也在另一侧)。
  • %g:g的截止规则略有不同。
  • %a!a不做同样的事情。

实际差异没有列在任何地方;你必须通过彻底阅读Format Specification Mini-Languageprintf-style String Formatting language来挖掘它们。

答案 1 :(得分:3)

使用pyupgrade

pyupgrade --py3-plus <filename>

您可以使用{p>而不是.format()来转换为f字符串(formatted string literals

pyupgrade --py36-plus <filename>

您可以使用

进行安装
pip install pyupgrade

答案 2 :(得分:2)

docs解释了一些差异。据我所知 - 尽管我对旧式格式字符串不是很熟悉 - 新样式的功能是旧式功能的超集。

你需要做更多调整来处理边缘情况,但我认为像

这样简单
re.replace(r'%(\w+)([sbcdoXnf...])', r'{\1\2}', your_string)

会让你90%的方式。剩余的翻译 - 从%x{0:x}之类的东西 - 对于正则表达式来说太复杂了(没有在你的正则表达式中编写一些可笑的复杂条件)。