Python代码阅读(第21篇):将变量名称转换为蛇式命名风格

本篇阅读的代码实现将变量名称转换为蛇式命名风格(snake case)的功能。

snake

from re import sub

def snake(s):
  return '_'.join(
    sub('([A-Z][a-z]+)', r' \1',
    sub('([A-Z]+)', r' \1',
    s.replace('-', ' '))).split()).lower()

EXAMPLES
snake('camelCase') # 'camel_case'
snake('some text') # 'some_text'
snake('some-mixed_string With spaces_underscores-and-hyphens') # 'some_mixed_string_with_spaces_underscores_and_hyphens'
snake('AllThe-small Things') # "all_the_small_things"

snake函数使用正则表达式将字符串变形、分解成单词,并加上 _作为分隔符组合起来。函数主要使用了 re模块的 substr.replacestr.splitstr.lowerstr.join。在正式分析 snake函数的逻辑之前,先介绍下其中使用到的其他函数的作用。

返回字符串的副本,其中出现的所有子字符串 old都将被替换为 new 如果给出了可选参数 count,则只替换前 count次出现。

返回一个由字符串内单词组成的列表,使用 sep作为分隔字符串。 如果给出了 maxsplit,则最多进行 maxsplit次拆分(因此,列表最多会有 maxsplit+1个元素)。 如果 maxsplit未指定或为 -1,则不限制拆分次数(进行所有可能的拆分)。

如果 sep未指定或为 None,则会应用另一种拆分算法:连续的空格会被视为单个分隔符,开头和结尾如果包含空格的话,将不会拆分出空字符串。 因此,使用 None拆分空字符串或仅包含空格的字符串将返回 []

>>> '1 2 3'.split()
['1', '2', '3']
>>> '1 2 3'.split(maxsplit=1)
['1', '2 3']
>>> '   1   2   3   '.split()
['1', '2', '3']

返回一个由 iterable中的字符串拼接而成的字符串。

返回其所有区分大小写的字符都转换为小写的原始字符串的副本。

[En]

Returns a copy of the original string whose all case-sensitive characters are converted to lowercase.

返回通过使用 repl替换在 string最左边非重叠出现的 pattern而获得的字符串。 如果样式没有找到,则不加改变地返回 stringrepl可以是字符串或函数。 向后引用像是 \6会用样式中第 6组所匹配到的子字符串来替换。 例如下面的例子中第一组匹配到的是 myfun,所以在替换的时候, \1使用 myfun替换,所以在结果中 \npy_后面接着的是 myfun

>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
...        r'static PyObject*\npy_\1(void)\n{',
...        'def myfunc():')
'static PyObject*\npy_myfunc(void)\n{'

首先分析一下 snake函数最里面的 sub函数。先看下输入参数。

strings.replace('-', ' ')将待转换的字符串中的 '-'使用 ' '替换。

pattern'([A-Z]+)',其中 (...)表示他是一个组合,匹配括号内的正则表达式,并在匹配完成之后,组合的内容可以被获取,并可以在之后用 \number转义序列进行再次匹配或使用,例如上个例子中的 \1'([A-Z]+)'的组合表示要匹配一个或多个大写字母,并尽可能匹配出最长的子字符串。

replr' \1',代表使用组合匹配出来的字符串前增加一个空格,替换匹配出来的字符串。例如 'abcDEF'经过匹配和替换将变成 'abc DEF'sub('([A-Z]+)', r' \1', 'abcDEF') # 'abc DEF'

因此, snake函数最里面的 sub函数的输出是将原始字符串中的 '-'使用 ' '替换,再匹配字符串中的一个或多个连续的大些字母,在前面增加一个空格。例如原始字符串是 'abc-abcDEF-ABc'经过第一个 sub函数转换后变成 'abc abc DEF ABc'(注意 'ABc'前面有两个空格)。

接下来再分析一下第二层的 sub函数。还是先看一下输入参数。

string是上个 sub的输出,在前面的例子中,是 'abc abc DEF ABc'(注意 'ABc'前面有两个空格)。

pattern'([A-Z][a-z]+)'。它也是一个组合,表示要匹配一个大写字母后面跟着一个或多个小写字母的形式,并尽可能匹配出最长的子字符串。

repl还是 r' \1',代表使用组合匹配出来的字符串前增加一个空格,替换匹配出来的字符串。

因此,第二层 sub的输出是简单的匹配一个大写字母后面跟着一个或多个小写字母的形式,在前面加一个空格。继续使用前面的例子,这层的输入字符串是 'abc abc DEF ABc'(注意 'ABc'前面有两个空格),输出是 'abc abc DEF A Bc'(注意 'A'前面有两个空格)。

然后 snake函数将第二层 sub输出的字符串使用 str.split函数分成字符串列表。再将得到的字符串列表使用 '-'作为分隔符组合起来。最后使用 str.lower将组合后的字符串转换成小写。延续上面的例子,最终输出的字符串为: 'abc_abc_def_a_bc'

Original: https://www.cnblogs.com/felixz/p/15437636.html
Author: FelixZ
Title: Python代码阅读(第21篇):将变量名称转换为蛇式命名风格

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/511040/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球