使用 re.compiler 提取数据的最佳方法

best way to extract data using re.compiler

我需要从不同的文本文件中提取(很多)信息。 我想知道是否有比以下更短更有效的方法:

第一部分:(N行长)

N1 = re.compile(r'')
N2 = re.compile(r'')
.
Nn = re.compile(r'')

第二部分:(2N行长)

with open(filename) as f:
  for line in f:
    if N1.match(line):
      var1 = N1.match(line).group(x).strip()
    elif N2.match(line):
      var2 = N1.match(line).group(x).strip()
    elif Nn.match(line):
      varn = Nn

您是否建议将 re.compile 变量(第 1 部分)与第 2 部分分开。在这种情况下,你们使用什么?也许是将正则表达式作为参数传递的函数?每次都调用它。

在我的例子中,N 是 30,这意味着我有 90 行来为字典提供很少的逻辑,或者根本没有逻辑。

re module documentation 中所述,您通过 re 方法传递的正则表达式已被缓存:根据您拥有的表达式数量,您自己缓存它们可能没有用。

也就是说,您应该列出您的正则表达式,这样一个简单的 for 循环就可以让您测试所有模式。

regexes = map(re.compile, ['', '', '', '', ...])
vars = ['']*len(regexes)
with open(filename) as f:
  for line in f:
    for i,regex in enumerate(regexes):
      if regex.match(line):
         var[i] = regex.match(line).group(x).strip()
         break  # break here if you only want the first match for any given line.

我将尝试在不真正了解您实际上在做什么的情况下回答这个问题。所以这个答案可能对你有帮助,也可能没有。

首先,re.compile做的是pre-compile一个正则表达式,以后可以用,不用每次都编译。当您有一个在整个程序中多次使用的正则表达式时,这主要有用。但是如果表达式只被使用几次,那么预先编译它并没有太大的好处。

所以您应该问问自己,代码 运行 尝试匹配所有这些表达式的频率。在脚本执行期间是否只有一次?然后您可以通过内联表达式使您的代码更简单。由于您要 运行 匹配文件中的每一行,因此 pre-compiling 在这里可能有意义。

但仅仅因为您 pre-compiled 表达式,并不意味着您应该马虎并且经常匹配相同的表达式。看这段代码:

if N1.match(line):
    var1 = N1.match(line).group(x).strip()

假设有匹配项,这将 运行 N1.match() 两次。这是您应该避免的开销,因为匹配表达式可能相对昂贵(取决于表达式),即使表达式已经是 pre-compiled.

相反,只匹配一次,然后重复使用结果:

n1_match = N1.match(line)
if n1_match:
    var1 = n1_match.group(x).strip()

查看您的代码,您的正则表达式似乎也是互斥的——或者至少您只使用第一个匹配项并跳过其余的匹配项。在这种情况下,您应该确保订购支票 这样最常见的检查首先完成。这样,您就可以避免 运行 设置太多无论如何都不匹配的表达式。此外,请尝试对它们进行排序,以便更复杂的表达式 运行 更少出现。

最后,您将在单独的变量中收集匹配结果 varN。在这一点上,我质疑你到底在做什么,因为在你所有的 if 检查之后,你没有一个明确的方法来弄清楚结果是什么以及要使用哪个变量。此时,将其收集在单个变量中或在条件体内移动特定逻辑可能更有意义。但是根据你提供的信息量很难判断。