如何在 Python 中使用正则表达式术语过滤迭代不同列表的文本?



有一个API服务可以接收超过6000个JSON文件。这些 JSON 中的每一个都有 11 个变量。

问题来了:

变量sd是字符串。变量s是名称,d是项目。有 4 个列表具有正则表达式值。这些列表的长度并不相同。

在一种情况下,如果变量s匹配 3 个名称列表中的某个名称,并且d匹配一个特定值,则该标志应为 False。

在其余情况下,如果变量sd与 4 个列表中的 RegEx 值匹配,则它应返回一个flag为 True 加上一个label(1, 2, 3(。

这是我尝试并失败的第一个函数:

def flag(s_text, d_text, filter_a, filter_b, filter_c, filter_e):
flag = False
label = ''
special_names_list = ['^OSCAR', 'ADRIANb', 'MORALES.*']
#CONSIDER THAT ALL TEXT IN THE REGEX FILTERS IS IN CAPITALS
s = s_text.upper()
d = d_text.upper()
for n in special_names_list:
if re.search(n, s) and re.search('BALL', d): #This is the one only case
flag = False
label = ''
#The following loops are over the lists containing RegEx filters
for a in filter_a:
if re.search(a, s):
flag = True
label = 2
for b in filter_b:
if re.search(b, d):
flag = True
label = 2
for c in filter_c:
if re.search(c, d):
flag = True
label = 1
for e in filter_e:
if re.search(e, d):
flag = True
label = 3
return flag, label

这是我尝试的第二个函数,也失败了:

def flag(s_text, d_text, filter_a, filter_b, filter_c, filter_e):
#All text is either received or converted in upper case.
flag = False
label = ''
special_names_list = [r'OSCAR.*',r'ADRIAN.*',r'MORALES.*']
s = s_text.upper()
d = d_text.upper()
# I thought to create a regex dictionary where the value of each key has the label I expect to be returned.
regex = {} 
for a in filter_a:
regex[a] = 2
for b in filter_b:
regex[b] = 2
for c in filter_c:
regex[c] = 1
for e in filger_e:
regex[e] = 3
for n in special_names_list:
if bool(re.match(n, s)) == True and bool(re.search('BALL', d)) == True:
flag = False
label = ''
break
else:
for k, v in regex.items():
if bool(re.search(k, s)) == True or bool(re.search(k, d)) == True:
flag = True
label = v
break
return flag, label

正确的函数应返回一个包含flag布尔值和label的元组,具体取决于每种情况,有一种情况的值''

此代码并非适用于所有情况,尤其是第一种情况。我一直在测试它,以尝试我能想到的所有可能性。我一直非常小心地输入与正则表达式匹配的值。

我认为有一种方法可以更轻松地构建该函数,在循环背后的逻辑上也缺少一些东西,以便更好地迭代。

额外信息:关键字'BALL'在其中一个筛选器列表中重复出现。这意味着对于sOSCARADRIANMORALES'BALL'存在于dflag时应该False,但是当s有任何其他值时,flag应该是True

在我的代码中,当我通过 OSCAR 和 BALL 时,它返回的标志为 True,而不是 False。

经过几次尝试和偶然的机会,我找到了答案,并理解了代码和逻辑上的几个错误:

  • 了解原始字符串

正如Wiktor向我解释的那样,正则表达式'ADRIANb应该转换为r'ADRIAN'b。我做了一些关于它的阅读,并理解了为什么它与我的关键字不匹配。

  • 2 个变量的 if 语句

对于我的第一个 IF 语句,我正在评估要在 2 个不同的正则表达式术语列表中匹配的某个单词。我还在同一语句中使用了IFAND。我不明白,虽然条件写得很好,但它不会独立地循环 2 个正则表达式列表,但同时。这意味着,为了匹配,必须在同一步找到这两个值。

解决方法是 2 个单独的 IF 语句和一个额外的变量,该变量为 True 或 False。喜欢这个:

for n in special_names_list:
if re.search(n, s):
validation = True
if re.search('BALL', d):
validation_2 = True
if validation = True and validation_2 = True:
return flag, label

如果在变量 d 上找到某个单词 ('BALL'(,并且在特殊名称变量列表中找到某个名称,这将能够传递单情况条件。

  • JSON 和 RegEx

正则表达式过滤规则来自使用pd.read_json导入的 JSON 文件。虽然在python中b执行某些功能,但在JSON中,我不得不添加额外的反斜杠\b。其他正则表达式条件不需要额外的关注,只需要反弹。

  • 循环和break

我不完全了解break在循环中的用法,或者它到底做了什么,但我将它们全部更改为return,因为我希望如果满足条件,它会停止循环。它确实做到了。

  • 测试

对于每个循环,无论是for还是if,我都创建了print语句来找出案例匹配的位置。

这是最后一个有效的函数:

def flag(s_text, d_text, filter_a, filter_b, filter_c, filter_e):
s = s_text.upper()
d = d_text.upper()
flag = False
label = ''
validation = False
validation_2 = False
if re.search(r'OSCAR.*b|ADRIAN.*b|MORALES.*b', s):
print('match name')
validation = True
if re.search(r'BALLb', d):
print('match special condition')
validation_2 = True
if validation == True and validation_2 == True:
return flag, label
else:
for a in filter_a:
if re.search(a, s):
print('match filter_a')
flag = True
label = 2
return flag, label
for b in filter_b:
if re.search(b, d):
print('match filter_b')
flag = True
label = 2
return flag, label
for c in filter_c:
if re.search(c, d):
print('match filter_c')
flag = True
label = 1
return flag, label
for e in filter_e:
if re.search(e, d):
print('match filter_e')
flag = True
label = 3 
return flag, label
return flag, label

最新更新