为什么我的 Regex 搜索产生的结果比预期的多,为什么我的循环没有删除某些重复项?
Why is my Regex search yielding more than expected and why isn't my loop removing certain duplicates?
我正在开发一个解析天气信息的程序。在我的这部分代码中,我尝试按时间顺序重新组织结果,然后再继续添加更多项目。
这些行中的时间通常是任何一行的前 4 位数字(前 2 位数字是日期,其他是小时)。例外是以 11010KT
开头的行,该行始终被假定为任何天气报告中的第一行,并且这些数字是风矢量而不是时间。
您会看到我正在删除此示例开头包含 TEMPO
INTER
或 PROB
的任何行,因为我希望将包含这些词的行添加到另一个重组列表的末尾。这些行可以被认为是一个单独的列表,我希望以与其他项目相同的方式按时间组织其中。
我正在尝试使用正则表达式从删除 TEMPO
INTER
和 PROB
行后剩余的行中提取时间,然后对它们进行排序,然后在排序后使用regex 再次完整地找到该行并创建一个重组列表。完成该列表后,我将对 TEMPO
INTER
和 PROB
列表进行排序,然后将其附加到我刚刚制作的新完成的列表中。
我还尝试了一个 for
循环,该循环将删除添加的任何重复行,但这似乎只删除了 TEMPO
行的一个副本???
有人可以帮我解决这个问题吗?我对此有点陌生,谢谢...
这理想情况下应该像这样回来:
ETA IS 0230 which is 1430 local
11010KT 5000 MODERATE DRIZZLE BKN004
FM050200 12012KT 9999 LIGHT DRIZZLE BKN008
TEMPO 0501/0502 2000 MODERATE DRIZZLE BKN002
INTER 0502/0506 4000 SHOWERS OF MODERATE RAIN BKN008
取而代之的是,我重复了以 FM050200
开头的行,然后重复了以 TEMPO
开头的行。它也没有找到以 INTER
开头的行...
我做了一个最小的可复制示例,供任何人尝试帮助我。我将把它包括在这里:
import re
total_print = ['\nFM050200 12012KT 9999 LIGHT DRIZZLE BKN008', '\n11010KT 5000 MODERATE DRIZZLE BKN004', '\nINTER 0502/0506 4000 SHOWERS OF MODERATE RAIN BKN008', '\nTEMPO 0501/0502 2000 MODERATE DRIZZLE BKN002']
removed_lines = []
for a in total_print: # finding and removing lines with reference to TEMPO INTER PROB
if 'TEMPO' in a:
total_print.remove(a)
removed_lines.append(a)
for b in total_print:
if 'INTER' in b:
total_print.remove(b)
removed_lines.append(b)
for f in total_print:
if 'PROB' in f:
total_print.remove(f)
removed_lines.append(f)
list_time_in_line = []
for line in total_print: # finding the times in the remaining lines
time_in_line = re.search(r'\d\d\d\d', line)
list_time_in_line.append(time_in_line.group())
sorted_time_list = sorted(list_time_in_line)
removed_time_in_line = []
for g in removed_lines: # finding the times in the lines that were originally removed
removed_times = re.search(r'\d\d\d\d', g)
removed_time_in_line.append(removed_times.group())
sorted_removed_time_list = sorted(removed_time_in_line)
final = []
final.append('ETA IS 1230 which is 1430 local\n') # appending the time display
search_for_first_line = re.search(r'[\n]\d\d\d\d\dKT', ' '.join(total_print)) # searching for line that has wind vector instead of time
search_for_first_line = search_for_first_line.group()
if search_for_first_line: # adding wind vector line so that its the firs line listed in the group
search_for_first_line = re.search(r'%s.*' % search_for_first_line, ' '.join(total_print)).group()
final.append('\n' + search_for_first_line)
print(sorted_time_list) # the list of possible times found (the second item in list is the wind vector and not a time)
d = 0
for c in sorted_time_list: # finding the whole line for the corresponding time
print(sorted_time_list[d])
search_for_whole_line = re.search(r'.*\w+\s*%s.*' % sorted_time_list[d], ' '.join(total_print))
print(search_for_whole_line.group()) # it is doubling up on the 0502 time???????
d += 1
final.append('\n' + str(search_for_whole_line.group()))
h = 0
for i in sorted_removed_time_list: # finding the whole line for the corresponding times from the previously removed items
whole_line_in_removed_srch = re.search(r'.*%s.*' % sorted_removed_time_list[h], ' '.join(removed_lines))
h += 1
final.append('\n' + str(whole_line_in_removed_srch.group())) # appending them
l_new = []
for item in final: # this doesn't seeem to properly remove duplicates ?????
if item not in l_new:
l_new.append(item)
total_print = l_new
print(' '.join(total_print))
///////////////////////////////////// //编辑:
我最近问过这个问题,@diggusbickus 对我的问题给出了很好的答案。我现在遇到了答案排序的新问题。
因为我原来的问题在我的data['other']
中只有一种天气线(以字母'FM'开头),所以lambda
和split()
只是暂时查看行 [0]
的第一项。
data['other'] = sorted(data['other'], key=lambda x: x.split()[0])
时间所在的位置(在上一个问题中是 FM050200
,其中 05 是日期,0200 是时间)。当有以 FM
开头的行时,这非常有效,但我意识到偶尔会存在这样的行:
'\nBECMG 0519/0520 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030'
这种行中的时间是位于索引 [1] 的前 4 位数字,并且采用 4 位格式而不是 FM050200
中的 6 位格式行。此新行中的时间是 05
作为日期,19
作为小时(所以 1900)。
我需要将这种样式的行与 FM
行分组,问题是它们无法排序。我正在尝试找到一种能够按时间对行进行排序的方法,而不管时间是在 [0]
索引上以 6 位格式还是在 [1]
索引上以 4 位格式。
我将包含一个新示例,其中对最初回答的问题进行了一些小改动。这个新问题将具有与 total_print
变量不同的数据。这是一个工作示例。
我基本上需要按任何行的前 4 位数字对行进行排序,结果应如下所示:
ETA IS 0230 which is 1430 local
FM131200 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010
FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010
BECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030
TEMPO 1312/1320 4000 SHOWERS OF MODERATE RAIN BKN007
注意。 TEMPO
行应该放在最后,所以不用担心那一行。
这是例子,非常感谢任何帮助的人。
import re
total_print = ['\nBECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030', '\nFM131200 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010', '\nFM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010','\nTEMPO 1312/1320 4000 SHOWERS OF MODERATE RAIN BKN007']
data = {
'windvector': [], # if it is the first line of the TAF
'other': [], # anythin with FM or BECMG
'tip': [] # tempo/inter/prob
}
wind_vector = re.compile('^\s\d{5}KT')
for line in total_print:
if 'TEMPO' in line \
or 'INTER' in line \
or 'PROB' in line:
key = 'tip'
elif re.match(wind_vector, line):
key = 'windvector'
else:
key = 'other'
data[key].append(line)
final = []
data['other'] = sorted(data['other'], key=lambda x: x.split()[0])
data['tip'] = sorted(data['tip'], key=lambda x: x.split()[1])
final.append('ETA IS 0230 which is 1430 local\n')
for lst in data.values():
for line in lst:
final.append('\n' + line[1:]) # get rid of newline
print(' '.join(final))
只需将您的数据排序到字典中,您总是在创建列表并删除项目:这太混乱了。
用于捕获风矢量的正则表达式也捕获 12012KT
,这就是重复该行的原因。 ^
确保它只匹配你的模式,如果它是行的开头
import re
total_print = ['\nFM050200 12012KT 9999 LIGHT DRIZZLE BKN008', '\n11010KT 5000 MODERATE DRIZZLE BKN004', '\nINTER 0502/0506 4000 SHOWERS OF MODERATE RAIN BKN008', '\nTEMPO 0501/0502 2000 MODERATE DRIZZLE BKN002']
data = {
'windvector': [],
'other': [],
'tip': [] #tempo/inter/prob
}
wind_vector=re.compile('^\s\d{5}KT')
for line in total_print:
if 'TEMPO' in line \
or 'INTER' in line \
or 'PROB' in line:
key='tip'
elif re.match(wind_vector, line):
key='windvector'
else:
key='other'
data[key].append(line)
data['tip']=sorted(data['tip'], key=lambda x: x.split()[1])
print('ETA IS 0230 which is 1430 local')
print()
for lst in data.values():
for line in lst:
print(line[1:]) #get rid of newline
我正在开发一个解析天气信息的程序。在我的这部分代码中,我尝试按时间顺序重新组织结果,然后再继续添加更多项目。
这些行中的时间通常是任何一行的前 4 位数字(前 2 位数字是日期,其他是小时)。例外是以 11010KT
开头的行,该行始终被假定为任何天气报告中的第一行,并且这些数字是风矢量而不是时间。
您会看到我正在删除此示例开头包含 TEMPO
INTER
或 PROB
的任何行,因为我希望将包含这些词的行添加到另一个重组列表的末尾。这些行可以被认为是一个单独的列表,我希望以与其他项目相同的方式按时间组织其中。
我正在尝试使用正则表达式从删除 TEMPO
INTER
和 PROB
行后剩余的行中提取时间,然后对它们进行排序,然后在排序后使用regex 再次完整地找到该行并创建一个重组列表。完成该列表后,我将对 TEMPO
INTER
和 PROB
列表进行排序,然后将其附加到我刚刚制作的新完成的列表中。
我还尝试了一个 for
循环,该循环将删除添加的任何重复行,但这似乎只删除了 TEMPO
行的一个副本???
有人可以帮我解决这个问题吗?我对此有点陌生,谢谢...
这理想情况下应该像这样回来:
ETA IS 0230 which is 1430 local
11010KT 5000 MODERATE DRIZZLE BKN004
FM050200 12012KT 9999 LIGHT DRIZZLE BKN008
TEMPO 0501/0502 2000 MODERATE DRIZZLE BKN002
INTER 0502/0506 4000 SHOWERS OF MODERATE RAIN BKN008
取而代之的是,我重复了以 FM050200
开头的行,然后重复了以 TEMPO
开头的行。它也没有找到以 INTER
开头的行...
我做了一个最小的可复制示例,供任何人尝试帮助我。我将把它包括在这里:
import re
total_print = ['\nFM050200 12012KT 9999 LIGHT DRIZZLE BKN008', '\n11010KT 5000 MODERATE DRIZZLE BKN004', '\nINTER 0502/0506 4000 SHOWERS OF MODERATE RAIN BKN008', '\nTEMPO 0501/0502 2000 MODERATE DRIZZLE BKN002']
removed_lines = []
for a in total_print: # finding and removing lines with reference to TEMPO INTER PROB
if 'TEMPO' in a:
total_print.remove(a)
removed_lines.append(a)
for b in total_print:
if 'INTER' in b:
total_print.remove(b)
removed_lines.append(b)
for f in total_print:
if 'PROB' in f:
total_print.remove(f)
removed_lines.append(f)
list_time_in_line = []
for line in total_print: # finding the times in the remaining lines
time_in_line = re.search(r'\d\d\d\d', line)
list_time_in_line.append(time_in_line.group())
sorted_time_list = sorted(list_time_in_line)
removed_time_in_line = []
for g in removed_lines: # finding the times in the lines that were originally removed
removed_times = re.search(r'\d\d\d\d', g)
removed_time_in_line.append(removed_times.group())
sorted_removed_time_list = sorted(removed_time_in_line)
final = []
final.append('ETA IS 1230 which is 1430 local\n') # appending the time display
search_for_first_line = re.search(r'[\n]\d\d\d\d\dKT', ' '.join(total_print)) # searching for line that has wind vector instead of time
search_for_first_line = search_for_first_line.group()
if search_for_first_line: # adding wind vector line so that its the firs line listed in the group
search_for_first_line = re.search(r'%s.*' % search_for_first_line, ' '.join(total_print)).group()
final.append('\n' + search_for_first_line)
print(sorted_time_list) # the list of possible times found (the second item in list is the wind vector and not a time)
d = 0
for c in sorted_time_list: # finding the whole line for the corresponding time
print(sorted_time_list[d])
search_for_whole_line = re.search(r'.*\w+\s*%s.*' % sorted_time_list[d], ' '.join(total_print))
print(search_for_whole_line.group()) # it is doubling up on the 0502 time???????
d += 1
final.append('\n' + str(search_for_whole_line.group()))
h = 0
for i in sorted_removed_time_list: # finding the whole line for the corresponding times from the previously removed items
whole_line_in_removed_srch = re.search(r'.*%s.*' % sorted_removed_time_list[h], ' '.join(removed_lines))
h += 1
final.append('\n' + str(whole_line_in_removed_srch.group())) # appending them
l_new = []
for item in final: # this doesn't seeem to properly remove duplicates ?????
if item not in l_new:
l_new.append(item)
total_print = l_new
print(' '.join(total_print))
///////////////////////////////////// //编辑:
我最近问过这个问题,@diggusbickus 对我的问题给出了很好的答案。我现在遇到了答案排序的新问题。
因为我原来的问题在我的data['other']
中只有一种天气线(以字母'FM'开头),所以lambda
和split()
只是暂时查看行 [0]
的第一项。
data['other'] = sorted(data['other'], key=lambda x: x.split()[0])
时间所在的位置(在上一个问题中是 FM050200
,其中 05 是日期,0200 是时间)。当有以 FM
开头的行时,这非常有效,但我意识到偶尔会存在这样的行:
'\nBECMG 0519/0520 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030'
这种行中的时间是位于索引 [1] 的前 4 位数字,并且采用 4 位格式而不是 FM050200
中的 6 位格式行。此新行中的时间是 05
作为日期,19
作为小时(所以 1900)。
我需要将这种样式的行与 FM
行分组,问题是它们无法排序。我正在尝试找到一种能够按时间对行进行排序的方法,而不管时间是在 [0]
索引上以 6 位格式还是在 [1]
索引上以 4 位格式。
我将包含一个新示例,其中对最初回答的问题进行了一些小改动。这个新问题将具有与 total_print
变量不同的数据。这是一个工作示例。
我基本上需要按任何行的前 4 位数字对行进行排序,结果应如下所示:
ETA IS 0230 which is 1430 local
FM131200 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010
FM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010
BECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030
TEMPO 1312/1320 4000 SHOWERS OF MODERATE RAIN BKN007
注意。 TEMPO
行应该放在最后,所以不用担心那一行。
这是例子,非常感谢任何帮助的人。
import re
total_print = ['\nBECMG 1315/1317 27007KT 9999 SHOWERS OF LIGHT RAIN SCT020 BKN030', '\nFM131200 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010', '\nFM131400 20010KT 9999 SHOWERS OF LIGHT RAIN SCT006 BKN010','\nTEMPO 1312/1320 4000 SHOWERS OF MODERATE RAIN BKN007']
data = {
'windvector': [], # if it is the first line of the TAF
'other': [], # anythin with FM or BECMG
'tip': [] # tempo/inter/prob
}
wind_vector = re.compile('^\s\d{5}KT')
for line in total_print:
if 'TEMPO' in line \
or 'INTER' in line \
or 'PROB' in line:
key = 'tip'
elif re.match(wind_vector, line):
key = 'windvector'
else:
key = 'other'
data[key].append(line)
final = []
data['other'] = sorted(data['other'], key=lambda x: x.split()[0])
data['tip'] = sorted(data['tip'], key=lambda x: x.split()[1])
final.append('ETA IS 0230 which is 1430 local\n')
for lst in data.values():
for line in lst:
final.append('\n' + line[1:]) # get rid of newline
print(' '.join(final))
只需将您的数据排序到字典中,您总是在创建列表并删除项目:这太混乱了。
用于捕获风矢量的正则表达式也捕获 12012KT
,这就是重复该行的原因。 ^
确保它只匹配你的模式,如果它是行的开头
import re
total_print = ['\nFM050200 12012KT 9999 LIGHT DRIZZLE BKN008', '\n11010KT 5000 MODERATE DRIZZLE BKN004', '\nINTER 0502/0506 4000 SHOWERS OF MODERATE RAIN BKN008', '\nTEMPO 0501/0502 2000 MODERATE DRIZZLE BKN002']
data = {
'windvector': [],
'other': [],
'tip': [] #tempo/inter/prob
}
wind_vector=re.compile('^\s\d{5}KT')
for line in total_print:
if 'TEMPO' in line \
or 'INTER' in line \
or 'PROB' in line:
key='tip'
elif re.match(wind_vector, line):
key='windvector'
else:
key='other'
data[key].append(line)
data['tip']=sorted(data['tip'], key=lambda x: x.split()[1])
print('ETA IS 0230 which is 1430 local')
print()
for lst in data.values():
for line in lst:
print(line[1:]) #get rid of newline