【问题标题】:Multi-line regex search in whole file整个文件中的多行正则表达式搜索
【发布时间】:2009-10-02 13:16:31
【问题描述】:

我找到了大量使用正则表达式替换文件中文本的示例。然而,这一切都归结为两个版本:
1. 遍历文件中的所有行并将正则表达式应用于每一行
2. 加载整个文件。

没有。 2 使用“我的”文件是不可行的 - 它们大约 2GiB...
至于第 1 号:目前这是我的方法,但我想知道......如果需要应用跨越多行的正则表达式怎么办?

【问题讨论】:

  • 是否可以将这些数据加载到 RDBMS 中?
  • 我认为您需要更好地描述您的数据和正则表达式以获得体面的建议。
  • 好的。一点澄清:我经常需要修改大型 csv 文件。 (例如 switch col 3 和 5)我发现,使用 regex 和 sed,我可以快速应用所需的修改。但是,我使用 The Regulator “开发”并测试我的正则表达式,这将导致“clr-regex”,然后必须将其翻译成 sed 语法。为了避免这种情况,我编写了一个小工具(c#),它可以让我将“clr-regex”应用于文件。现在:使用此工具,无法应用跨越多行的正则表达式 - 因为我正在执行上述方法。 1. 上述问题有些假设性。
  • 请通过编辑问题进行澄清,而不是添加 cmets。
  • 瑞恩,谢谢。我想我是在 2010 年的某个时候开始这样做的 ;-)

标签: c# .net regex large-files


【解决方案1】:

这是答案:
没有简单的方法

我找到了一个StreamRegex-Class,它可以做我正在寻找的事情。
从我能掌握的算法来看:

  • 从文件开头用一个空缓冲区开始
  • 做(
    • 将文件块添加到缓冲区
    • 如果缓冲区中有匹配项
      • 标记匹配
      • 从缓冲区中删除比赛结束前出现的所有数据
  • ) 虽然文件还剩下一些东西

这样就不必加载完整文件了——或者至少减少了将完整文件加载到内存中的机会...
但是:最坏的情况是整个文件中没有匹配项 - 在这种情况下,整个文件将被加载到内存中。

【讨论】:

    【解决方案2】:

    正则表达式不是要走的路,尤其是对于这些大量文本。 创建自己的小解析器:

    • 逐行读取文件;
    • 对于每一行:
      • 逐个字符循环遍历行,跟踪任何字符 打开/关闭字符串文字
      • 当您遇到“/*”时(并且您不在“内部”字符串中), 存储该偏移量并循环,直到遇到 第一个 '*/' 并存储该数字

    这将为您提供注释块的所有起始偏移量和结束偏移量。您现在应该能够通过创建一个临时文件并将文本从原始文件写入临时文件来替换它们(当然,如果您在注释块内,还可以编写其他内容)。

    编辑:2GiB的源文件??

    【讨论】:

    • 我说的是来源吗? ;-) 没有“原始”数据,实际上是 csv。
    • 啊,我明白了。不懂 C#,但会想象它甚至不可能创建这么大的源文件。
    【解决方案3】:

    也许您可以一次加载 2 行(或更多,取决于您认为匹配将跨越多少行),并将它们重叠,例如:加载第 1-2 行,然后下一个循环加载行2-3,下加载3-4;并在每个循环中对两行合并执行多行正则表达式。

    【讨论】:

    • 好主意,但是每一行都可能被正则表达式多次。必须考虑可能的副作用..
    • 嗯,是的,你是对的。可能只在匹配从第一行开始时(在任何换行符之前)匹配?
    【解决方案4】:

    我会说您应该在进行替换之前对数据进行预解析/规范化,以便每一行都描述需要应用替换的一组可能的数据。否则,您会遇到数据完整性问题,如果没有许多其他困难,就无法真正解决。

    如果有办法将数据分块成逻辑块,那么您可以构建一个使用 mapreduce 模式来解析数据的程序。

    【讨论】:

      【解决方案5】:

      我和巴特在一起;你真的应该为此使用某种解析器。

      或者,如果您不介意生成子进程,则可以使用sed(有native port on windows,或者您可以使用Cygwin

      【讨论】:

        【解决方案6】:

        如果您不介意弄脏手(并且您的正则表达式足够简单,或者您可能对速度有强烈的渴望并且不介意受苦),您可以使用Ragel。它可以针对 C#,尽管该站点没有提及它。您需要包装 FileStream 以提供缓冲索引器或在 64 位进程中使用内存映射文件(带有不安全指针)来处理大文件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-03-04
          • 2011-02-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多