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

dis*_*ive 5 python

我有一系列按顺序调用的正则表达式。我需要检查第一个,然后是第二个,然后是第三个等等,直到最后。我需要对匹配的字符串进行一些处理,所以我试图避免太多的逻辑,但在 python 中,与 perl 不同,我不认为我可以在 ..blocks 中执行赋值,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:
       ......
Run Code Online (Sandbox Code Playgroud)

理想情况下,我希望找到一个更好的结构,确保保留测试的正则表达式的顺序,并且可以将赋值合并到 if-then 语句中。例如:

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]
...
Run Code Online (Sandbox Code Playgroud)

处理这个问题最Pythonic的方法是什么?谢谢。

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

che*_*ner 2

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
Run Code Online (Sandbox Code Playgroud)

这将迭代正则表达式对及其匹配的相关部分,直到找到匹配。如果没有找到匹配项,则将执行循环else的子句。无论哪种模式匹配,for匹配的结果都会在循环之后找到。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
Run Code Online (Sandbox Code Playgroud)

不过,总体思路是注意语句链if就像硬编码的迭代,因此您只需识别每个if/elif子句的哪些部分与前面的部分不同,并创建一个可以迭代的列表。