簡體   English   中英

如何在Python中獲取第一個大寫字母,然后再獲取每個不跟另一個大寫字母的字母?

[英]How to get the first capital letter and then each that isn't followed by another capital letter in Python?

我正在開發一個腳本,該腳本為一個我無法使用的名稱列表創建縮寫。 我需要將每個名稱分成多個點,然后將每個大寫字母都放在單詞的開頭。 像這樣:

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)  

說明:

  • ([AZ]) :大寫字母
  • (?: ) :):這是一個分組,以明確|范圍是什么| 里面的操作。 這不是上面的捕獲組(因此將被刪除)
  • [AZ]* :零個或多個大寫字母(貪心)
  • (?=[AZ]) :應該再加上一個大寫字母,但不要對其進行處理-留給下一場比賽
  • | :邏輯或
  • [^AZ.]* :零個或多個非大寫非點數(緊隨大寫字母之后):這些將被刪除
  • \\.(\\d+) :一個文字點后跟一個或多個數字:捕獲數字(以丟棄點)。

在替換參數中,捕獲的組再次注入:

  • \\1 :第一個捕獲組(這是大寫字母)
  • \\2 :第二個捕獲組(這些是點后面的數字)

在一個匹配中,只有一個捕獲組將具有某些內容,另一個則只是空字符串。 但是,正則表達式匹配會在整個輸入字符串中重復進行。

這是一個非正則表達式的解決方案。

def shorten(i):
    abr_list = []
    abrev = ''
    parts = i.split('.')
    for word in parts:
        for x in range(len(word)):
            if x == 0 and word[x].isupper() or word[x].isupper() and not word[x + 1].isupper() or word[x].isnumeric():
                abrev += word[x]
        abr_list.append(abrev)
        abrev = ''
    return join_parts(abr_list)


def join_parts(part_list):
    ret = part_list[0]
    for part in part_list[1:]:
        if not part.isnumeric():
            ret += '.%s' % part
        else:
            ret += part
    return ret
import re
def foo(s):
    print(''.join(list(map(
        lambda matchobj: matchobj[0], re.finditer(
            r'(?<![A-Z])[A-Z]|[A-Z](?![A-Z])|\.', s)))))
foo('InternetGatewayDevice.DeviceInfo.Description')
foo('WANDevice')
# output: 
# IGD.DI.D
# WD

正則表達式包含三個主要部分:

  1. 如果是大寫字母,但前面沒有大寫字母,則匹配(?<![AZ])[AZ]
  2. 如果是[AZ](?![AZ])后沒有大寫字母,則匹配
  3. 如果是字面上的時期

https://docs.python.org/3.6/library/re.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM