使代码不那么复杂,更具可读性
Make code less complex and more readable
我需要重写我的简单代码。我得到如下简单的字符串:
- 分发 ABC 1-2-x
- 分配 ABC DEF 1-2-x
- 分发 ABC DEF GHI 1-2-x
我要在 "Distrib " 之后使用 .split() 所有单词,并且我必须满足以下条件:
如果 string[0] 是文本 && string[1] 是整数,则仅加入这些以获得结果 "ABC/1"
如果 string[0] 是文本 && string[1] 是文本只连接它们然后得到结果 "ABC/DEF"
如果 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']
我需要重写我的简单代码。我得到如下简单的字符串:
- 分发 ABC 1-2-x
- 分配 ABC DEF 1-2-x
- 分发 ABC DEF GHI 1-2-x
我要在 "Distrib " 之后使用 .split() 所有单词,并且我必须满足以下条件:
如果 string[0] 是文本 && string[1] 是整数,则仅加入这些以获得结果 "ABC/1"
如果 string[0] 是文本 && string[1] 是文本只连接它们然后得到结果 "ABC/DEF"
如果 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']