【问题标题】:Regexp search through a very large file正则表达式搜索一个非常大的文件
【发布时间】:2012-12-28 15:58:02
【问题描述】:

我需要使用正则表达式扫描一个 300MB 的文本文件。

  • 读取整个文件并将其放入变量中会占用超过 700MB 的 RAM,然后失败并出现“无法分配内存”错误。
  • 匹配可以是两行或三行,所以我不能在循环中使用行到行步进。

是否有任何惰性方法可以使用正则表达式进行完整文件扫描而不将其读取到单独的变量中?

UPD

完成。现在您可以使用此功能按块读取。 根据您的目标对其进行修改。

def prepare_session_hash(fname, regex_string, start=0)
  @session_login_hash = {}
  File.open(fname, 'rb') { |f|
    fsize = f.size
    bsize = fsize / 8
    if start > 0
      f.seek(start)
    end

    overlap = 200

    while true
      if (f.tell() >= overlap) and (f.tell() < fsize)
        f.seek(f.tell() - overlap)
      end
      buffer = f.read(bsize)
      if buffer
        buffer.scan(s) { |match|
          @session_login_hash[match[0]] = match[1]
        }
      else
        return @session_login_hash
      end
    end
  }
end

【问题讨论】:

    标签: ruby regex


    【解决方案1】:
    1. 以块的形式遍历文件,而不是逐行遍历文件,其中块是由频繁出现的字符或模式的出现创建的,例如“X”。
    2. “X”是这样的,它永远不会存在于您的正则表达式中,即“X”是您的正则表达式永远不会匹配字符串的位置。
    3. 在当前块中匹配您的正则表达式,提取匹配项并继续下一个块。

    例子:

    This is string with multline numbers -2000
    2223434
    34356666
    444564646
    . These numbers can occur at 34345
    567567 places, and on 67
    87878 pages . The problem is to find a good
    way to extract these more than 100
    0 regexes without memory hogging.
    

    在本文中,假设所需的模式是数字字符串,例如 /d+/s 匹配数字多行, 然后,您可以选择一个块创建模式,而不是处理和加载整个文件,在这种情况下说 FULL STOP . 并且只读取和处理直到这个模式,然后移动到下一个块。

    CHUNK#1:

    This is string with multline numbers -2000
    2223434
    34356666
    444564646
    .
    

    CHUNK#2:

    These numbers can occur at 34345
    567567 places, and on 67
    87878 pages
    

    等等。

    编辑: 还添加了来自 cmets 的 @Ranty 的建议:

    或者简单地读几行,比如 20 行。当你找到 匹配内,清除到匹配结束并附加另外 20 行。 无需计算频繁出现的“X”。

    【讨论】:

    • 或者简单地读取一些行数,比如 20 行。当您在其中找到匹配项时,清除匹配项并追加另外 20 行。无需计算频繁出现的“X”。
    猜你喜欢
    • 2014-05-04
    • 1970-01-01
    • 1970-01-01
    • 2020-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多