用于将print...转换为print(...)的vim正则表达式(从Python2到Python3)

17 投票
3 回答
4694 浏览
提问于 2025-04-17 23:31

这篇帖子只有在你使用打印命令时有字符串的情况下才有帮助。现在我有很多源代码,其中有这样的语句:

print milk,butter

这些语句应该格式化成:

print(milk,butter)

而且用\n来捕捉行尾并没有成功。有什么建议吗?

3 个回答

6

既然你已经在使用vim编辑器了:

:!2to3 --fix=print --write %
12

你可以使用 2to3 工具,只针对打印语句进行修复,把它们转换成打印函数。

2to3 --fix=print [yourfiles]

这个工具会自动处理那些用其他方法,比如用 vim 的正则表达式,可能无法处理的奇怪情况。

如果你因为某种原因找不到 2to3 的脚本,可以把它作为一个模块来运行:

python -m lib2to3 --fix=print [yourfiles]
14

我对2to3不太熟悉,但从大家的评论来看,这似乎是个合适的工具。

不过,我们可以借这个问题来简单讲讲一些vim的基础知识。

首先,你需要一个能匹配正确行的模式。我觉得 ^\s*print\> 可以用:

  • ^ 表示行的开头(而 $ 表示行的结尾)。
  • \s 表示空白字符(空格或制表符)。
  • * 表示前面的字符可以出现0次或多次(尽可能多,或者说是“贪婪”)。
  • print 是一个字面字符串。
  • \> 表示单词的结束(宽度为零)。你也可以用一个(字面)空格或者 \s\+ 来代替。

接下来,你需要确定要用括号括起来的部分。因为 * 是贪婪的,所以 .* 会匹配到行的结尾;不需要在右边加锚点。使用 \(\s*print\)\(.*\) 来捕获这些部分,这样在替换时就可以用 \1\2 来引用它们。

现在,把这些部分组合起来。这里有很多变体,我没有尝试去简化这个:

:%s/^\(\s*print\)\s\+\(.*\)/\1(\2)

有些人喜欢“非常魔法”的版本,在这个版本中,只有a-z、A-Z、0-9和_被视为字面字符;这样你就不需要转义括号和加号:

:%s/^\v(\s*print)\s+(.*)/\1(\2)

撰写回答