在正则表达式上删除if-elif的智能python方法

在正则表达式上删除if-elif的智能python方法,python,Python,我有一系列reg表达式,称为顺序。我需要检查第一个,然后是第二个,然后是第三个等等,一直到最后。我需要对匹配的字符串进行一些处理,因此我试图避免太多的逻辑,但在python中,与perl不同,我认为我不能在if elif elif中执行赋值。因此,我将完成赋值,然后检查匹配,然后获得匹配的结果。例如: m = re.search(patternA, string) if m: stripped = m.group(0) xyz = stripped[45:67] elif: m =

我有一系列reg表达式,称为顺序。我需要检查第一个,然后是第二个,然后是第三个等等,一直到最后。我需要对匹配的字符串进行一些处理,因此我试图避免太多的逻辑,但在python中,与perl不同,我认为我不能在
if elif elif
中执行赋值。因此,我将完成赋值,然后检查匹配,然后获得匹配的结果。例如:

m = re.search(patternA, string)
if m:
  stripped = m.group(0)
  xyz = stripped[45:67]
elif:
  m = re.search(patternB, string)
  if m:
    stripped = m.group(0)
    abc = stripped[5:7]
  elif:
     m = re.search(patternB, string)
     if m:
       stripped = m.group(0)
       txt = stripped[4:5]
     elif:
       ......
if (m = re.search(patternA, string)):
  stripped = m.group(0)
  xyz = stripped[45:67]
elif (m = re.search(patternB, string)):
  stripped = m.group(0)
  abc = stripped[5:7]
...
理想情况下,我希望找到一个更好的结构,以确保保留已测试正则表达式的顺序,并且可以将赋值合并到if-then语句中。例如:

m = re.search(patternA, string)
if m:
  stripped = m.group(0)
  xyz = stripped[45:67]
elif:
  m = re.search(patternB, string)
  if m:
    stripped = m.group(0)
    abc = stripped[5:7]
  elif:
     m = re.search(patternB, string)
     if m:
       stripped = m.group(0)
       txt = stripped[4:5]
     elif:
       ......
if (m = re.search(patternA, string)):
  stripped = m.group(0)
  xyz = stripped[45:67]
elif (m = re.search(patternB, string)):
  stripped = m.group(0)
  abc = stripped[5:7]
...
什么是处理这件事的最好的方法?谢谢

用例是读取旧数据-非常旧的数据。但是,每个字符串可能包含关于特定值的信息,并且只有当正则表达式匹配特定模式时,这些信息才会出现。因此,提取的变量高度依赖于匹配的内容

for (pattern, slice) in zip([patternA, patternB, patternC],
                            [slice(45,67), slice(5,7), slice(4,5)]):
    m = re.search(pattern, string)
    if m:
        value = m.group(0)[slice]
        break
else:
    # Handle no match found for any pattern here
这将迭代正则表达式对及其匹配的相关部分,直到找到匹配项。如果没有找到匹配项,将执行
for
循环的
else
子句。无论哪种模式匹配,匹配结果都会在循环后的
value
中找到

根据哪个“分支”成功设置不同的变量不是一个好主意,因为您不一定知道在任何给定时间设置了哪些变量。如果您真的希望每个匹配都有单独的标签,那么最好使用字典,因为您可以查询字典中设置了哪些键

value = {}
for (pattern, slice, key) in zip([patternA, patternB, patternC],
                                 [slice(45,67), slice(5,7), slice(4,5)],
                                 ['abc', 'xyx', 'txt']):
    m = re.search(pattern, string)
    if m:
        value[key] = m.group(0)[slice]
        break

不过,一般的想法是要注意,您的
if
语句链类似于硬编码的迭代,因此您只需确定每个
if/elif
子句的哪些部分与前面的部分不同,并创建一个可以迭代的列表。

为什么要将结果分配给不同的目标或切片?通常,您会使用分组来选择真正想要提取的文本。作为一种黑客,您可以编写一个函数,接受
re.search()
的结果,并将其分配给您也传入的对象的属性,返回
True
False
。但是eww。@MartijnPieters有不同的变量,每一组位置/切片都依赖于reg表达式。@MartijnPieters我想他的意思是你可以使用一个捕获组来选择你真正想要的文本。然后,您可以将正则表达式放入一个列表中,并尝试每个正则表达式(使用循环),直到找到匹配项,然后从第一个捕获组中提取文本。@cdhowie:切片也可以寻址(使用
slice()
对象),但我真的不明白为什么在这里使用它们。更大的问题是给完全不同的名字赋值,我无法想象为什么会这样做。我喜欢它,它很优雅。每个reg表达式只有几个变量,因为有多个切片。必须进一步迭代这些切片/变量。+1:我不敢相信我不知道它的存在!zip很酷-很久以前没有学过它,但在生气时从不使用它。最后,我使用多个zip来处理变量键。