命名规范与正则表达式

本文链接个人站 | 简书 | CSDN
版权声明:除特别声明外,本博客文章均采用 BY-NC-SA 许可协议。转载请注明出处。

根据 Google Python Style Guide,Python 中的参数名一般为 lower_with_under 风格。而根据 Google Java Style Guide, Java 中的参数名一般为 lowerCamelCase 风格。那么问题来了,假如你写了一个 Python 算法服务供 Java 后端调用,设计接口的时候参数名应该采用什么命名风格呢?我工作中就遇到过这个问题。使用 Python 风格吧,后端同学用起来不方便;使用 Java 风格吧,作为一个强迫症我又很难受。有没有两全其美的办法呢?

后端在调用接口的时候,使用 json 格式传递参数,算法接收到之后将 json 串反序列化为字典。借助正则表达式,我们可以把字典的 key 由 Java 风格转化为 Python 风格:

import re

def camel_to_snake(camelCase: str) -> str:
    """
    convert CamelCase string into snake_case string.
    """
    pattern = re.compile(r'([a-z]|\d)([A-Z])')
    snake_case = re.sub(
        pattern=pattern,
        repl=r'\1_\2',
        string=camelCase).lower()
    return snake_case

等等……我们不会是要遍历字典,逐个转换吧?如果是字典套字典的情况呢?难不成还写个递归?写这样的代码不会挨打吗?其实大可不必如此,我们可以在接收到 json 串之后先用正则表达式匹配出 key,一次性转换,然后再将 json 反序列化。

def json_camel_to_snake(camelCaseJsonStr: str) -> str:
    """
    convert CamelCase keys inside a json string into snake_case keys.
    """
    pattern = re.compile(r'"\s*(\w+)\s*"\s*:')
    snake_case_json_str = re.sub(
        pattern=pattern,
        repl=lambda s: '"' + camel_to_snake(s.group(1)) + '":',
        string=camelCaseJsonStr
    )
    return snake_case_json_str

进一步地,我们的算法服务的返回结果也可以在序列化为 json 串后,用正则表达式把所有的 key 从 Python 风格一键转化为 Java 风格,然后再传给用户。

def snake_to_camel(snake_case: str) -> str:
    """
    convert snake_case string into CamelCase string.
    """
    pattern = re.compile(r'(_\w)')
    camelCase = re.sub(
        pattern=pattern,
        repl=lambda s: s.group(1)[1].upper(),
        string=snake_case
    )
    return camelCase

def json_snake_to_camel(snake_case_json_str: str) -> str:
    """
    convert snake_case keys inside a json string into CamelCase keys.
    """
    pattern = re.compile(r'"\s*(\w+)\s*"\s*:')
    camelCaseJsonStr = re.sub(
        pattern=pattern,
        repl=lambda s: '"' + snake_to_camel(s.group(1)) + '":',
        string=snake_case_json_str
    )
    return camelCaseJsonStr

完。