对于格式不正确的 python 代码,在 sed 中将驼峰式命名为 snake_case

camelCase to snake_case in sed for ill formatted python code

我有一些 python 代码是用驼峰命名法写的,但是根据 PEP 8 变量名应该写成 snake_case。我写了一个小的 sed 脚本,它设法接受任何小写字母 \1,然后是大写字母 \2,然后将其变成 \1_ 和小写字母 \2

find . -iname \*.py | xargs sed -i "s/\([a-z]\)\([A-Z]\)/_\L/g"

但是这会将 CamelCase 变成 Camel_case。根据相同的 PEP 8 标准 class 名称应以大写字母开头的 CamelCase 书写。

我如何编写一个不使用 CamelCase 而是将 camelCamelCamelCamelCamel... 翻译成 camel_camel_camel_camel...[=28 的 sed 脚本=]?

我感觉我正在达到正则表达式的极限,因为我必须在未知数量的 "camel humps" 中保持以小写字母开头的单词的上下文。我知道我可以在另一个工具中做到这一点,但我想知道 sed 是否可以做到这一点。对此不可能的论证也足够了。

我正在使用 GNU sed 4.2.2

试试这个:

result = re.sub("([A-Z])", r"_", text, 0, re.MULTILINE)

其中一条评论提到 autopep8,这可能是选择 OP 的方式,但在 sed 中尝试这样做很有启发意义(我的意思是这是一个有趣的谜题)。

这是可能的:

sed -r ':loop; /.*\<([a-z]+([A-Z][a-z]+)+)\>.*/ { h; s///; s/([A-Z])/_\l/g; G; s/(.*)\n(.*)\<[a-z]+([A-Z][a-z]+)+\>(.*)//; b loop }'

密码是

:loop
/.*\<([a-z]+([A-Z][a-z]+)+)\>.*/ {
  h
  s///
  s/([A-Z])/_\l/g
  G
  s/(.*)\n(.*)\<[a-z]+([A-Z][a-z]+)+\>(.*)//
  b loop
}

这里,\<[a-z]+([A-Z][a-z]+)+\> 匹配一个 dromedaryCase 术语。 \<\>是词界,保证这个匹配这样的词。所以这是一个循环:

  1. 如果该行包含 dromedaryCase 术语:
  2. 将整行保存到保持缓冲区
  3. 分离 dromedaryCase 术语。这利用了 // 重用最后一个正则表达式这一事实,即来自 1.
  4. 的正则表达式
  5. 将所有大写字母替换为 _,然后是对应的小写字母(这使用 GNU 扩展 \l;否则您需要 y/ABCDEF.../abcdef.../ 命令来更改案件)。模式 space 现在包含与 dromedaryCase 术语对应的 snake_case。
  6. 将保留缓冲区中的原始行附加到模式 space
  7. 在原始正则表达式的基础上,将模式 space 拆分为相关部分:</code> 是 snake_case 项,<code> 是原始行的一部分在替换部分之前,是dromedaryCaseTerm之后的部分。然后按照正确的顺序重新组装这些零件。
  8. 循环直到替换行中的所有 dromedaryCase 术语。