使代码不那么复杂,更具可读性

Make code less complex and more readable

我需要重写我的简单代码。我得到如下简单的字符串:

我要在 "Distrib " 之后使用 .split() 所有单词,并且我必须满足以下条件:

  1. 如果 string[0] 是文本 && string[1] 是整数,则仅加入这些以获得结果 "ABC/1"

  2. 如果 string[0] 是文本 && string[1] 是文本只连接它们然后得到结果 "ABC/DEF"

  3. 如果 string[0] 是文本 && string[1] 是文本 && string[2] 是文本 将它们全部连接起来并得到结果:"ABC/DEF/GHI"

我写了一个简单的代码来执行此操作,但我真的很感兴趣如何编写更简单、更易读的代码;)

import re

def main_execute():
    #input_text = "Distrib ABC 1-2-x"
    #input_text = "Distrib ABC DEF 1-2-x"
    #input_text = "Distrib ABC DEF GHI 1-2-x"

    print(str(input_text))
    load_data = re.search('\s[A-Z]*.[A-Z]*.[A-Z]+ [0-9]', input_text).group()
    print("Pobrany ciąg znaków: " + load_data)

    words_array = load_data.split()

    if re.match('[0-9]', words_array[1]):
        print("Złożony ciąg: "
              + words_array[0]
              + "/"
              + words_array[1])
        elif re.match('[A-Z]', words_array[0]) and re.match('[A-Z]', words_array[1]) and re.match('[0-9]', words_array[2]):
        print("Złożony ciąg: "
              + words_array[0]
              + "/"
              + words_array[1])
    elif re.match('[A-Z]', words_array[0]) and re.match('[A-Z]', words_array[1]) and re.match('[A-Z]', words_array[2]) and re.match('[0-9]', words_array[3]):
        print("Złożony ciąg: "
              + words_array[0]
              + "/"
              + words_array[1]
              + "/"
              + words_array[2])


    if __name__ == "__main__":
        main_execute()

这可以大大简化为

import re

data = """
Distrib ABC 1-2-x
Distrib ABC DEF 1-2-x
Distrib ABC DEF GHI 1-2-x
"""

rx = re.compile(r'Distrib (\w+) (\w+)\s*((?:(?!\d)\w)+)?')

results = ["/".join([n for n in m.groups() if n]) for m in rx.finditer(data)]
print(results)

产生

['ABC/1', 'ABC/DEF', 'ABC/DEF/GHI']

查看表达式 on regex101.com 的演示。


@Wiktor 提出的另一种方法可能是

Distrib (\w+) (\w+)\s*([^\W\d]+)?

[^\W\d]+部分说的是:不是不是(加倍没有错!)单词字符,不是数字,尽可能长。

基于@Jan 的回答,您可以使用以下方法使正则表达式更易于阅读:

import re

data = """
Distrib ABC 1-2-x
Distrib ABC DEF 1-2-x
Distrib ABC DEF GHI 1-2-x
"""

rx = re.compile(r'Distrib ([A-Z]+) ([A-Z0-9]+) ?([A-Z]*)')

results = ["/".join([n for n in m.groups() if n]) for m in rx.finditer(data)]
print(results)

结果相同:

['ABC/1', 'ABC/DEF', 'ABC/DEF/GHI']