python - 如何获取第一个大写字母,然后在 Python 中获取每个大写字母后面没有的另一个大写字母?

标签 python python-3.x

我正在开发一个脚本,为我无法使用的太长的名称列表创建缩写。我需要将每个名字分成由点分隔的部分,然后取一个单词开头的每个大写字母。就像这样:

InternetGatewayDevice.DeviceInfo.Description -> IGD.DI.D

但是,如果有更多连续的大写字母(如下例所示),我只想取第一个,然后取的那个用大写字母。所以,我想从“WANDevice”获取“WD”。像这样:

InternetGatewayDevice.WANDevice.1.WANConnectionDevice.1.WANIPConnection.1.PortMapping.7.ExternalPort -> IGD.WD1.WCD1.WC1.PM7.EP

到目前为止我已经写了这个脚本:

data = json.load(open('./cwmp/tr069/test.json'))

def shorten(i):
    x = i.split(".")
    abbreviations = []
    for each in x:
        abbrev = ''
        for each_letter in each:
            if each_letter.isupper():
                abbrev = abbrev + each_letter
        abbreviations.append(abbrev)
    short_string = ".".join(abbreviations)
    return short_string

for i in data["mappings"]["cwmp_genieacs"]["properties"]:
    if "." in i:
        shorten(i)
    else:
        pass    

它正确地“翻译”了第一个示例,但我不确定如何完成其​​余部分。我想如果必须的话,我可能会想到一些的方法来做到这一点(比如可能将字符串拆分成单个字符),但我正在寻找一种高效且智能的方法来做到这一点。如果有任何建议,我将不胜感激。

我正在使用 Python 3.6。

编辑:

我决定尝试一种不同的方法并迭代单个字符,我很容易地实现了我想要的。不过,感谢您的回答和建议,我一定会仔细阅读。

def char_by_char(i):
    abbrev= ""
    for index, each_char in enumerate(i):
        # Define previous and next characters 
        if index == 0:
            previous_char = None
        else:
            previous_char = i[index - 1]

        if index == len(i) - 1:
            next_char = None
        else:
            next_char = i[index + 1]
        # Character is uppercase
        if each_char.isupper():
            if next_char is not None:
                if next_char.isupper():
                    if (previous_char is ".") or (previous_char is None):
                        abbrev = abbrev + each_char
                    else:
                        pass
                else:
                    abbrev = abbrev + each_char
            else:
                pass
        # Character is "."
        elif each_char is ".":
            if next_char.isdigit():
                pass
            else:
                abbrev = abbrev + each_char

        # Character is a digit              
        elif each_char.isdigit():
            abbrev = abbrev + each_char

        # Character is lowercase            
        else:
            pass
    print(abbrev)


for i in data["mappings"]["cwmp_genieacs"]["properties"]:
    if "." in i:
        char_by_char(i)
    else:
        pass    

最佳答案

您可以为此使用正则表达式。例如,您可以对要保留的字符使用捕获组,并在只保留那些捕获的字符的地方执行替换:

import re

def shorten(s):
    return re.sub(r'([A-Z])(?:[A-Z]*(?=[A-Z])|[^A-Z.]*)|\.(\d+)[^A-Z.]*', r'\1\2', s)  

解释:

  • ([A-Z]):捕获一个大写字母
  • (?: ):这是一个分组,用于明确其中的 | 操作的范围。这不是像上面那样的捕获组(因此将被删除)
  • [A-Z]*:零个或多个大写字母(贪心)
  • (?=[A-Z]):应该再跟一个大写字母,但不要处理它——留到下一场比赛
  • |:逻辑或
  • [^A-Z.]*:零个或多个非大写,非点(在捕获的大写字母之后):这些将被删除
  • \.(\d+):一个字面上的点后跟一个或多个数字:捕获数字(以便丢弃点)。

在替换参数中,再次注入(inject)捕获的组:

  • \1:第一个捕获组(这是大写字母)
  • \2:第二个捕获组(这些是点后的数字)

在一场比赛中,只有一个捕获组会有东西,另一个只是空字符串。但是正则表达式匹配在整个输入字符串中重复进行。

关于python - 如何获取第一个大写字母,然后在 Python 中获取每个大写字母后面没有的另一个大写字母?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49050197/

相关文章:

python - 更改光标在条目小部件中的位置

Python 使用 Fabric 模块向组运行 SSH 命令

python - 没有名为 'socks' 的模块

python - 扩展空列表使第一个元素为空

Pythonic 整数乘法和加法

python - 选项解析器与参数不匹配

python - Twitter API 速率限制问题

python - 如何在 python 中关闭 udp 套接字

python - Python中使用"else"之后的"if"语句之前执行的`undo`语句

Python 卡住的可执行文件在某些​​计算机上无法运行