【问题标题】:How can I match multi-line patterns in the command line with perl-style regex?如何将命令行中的多行模式与 perl 样式的正则表达式匹配?
【发布时间】:2014-06-12 01:44:27
【问题描述】:

我经常使用正则表达式来转换文本。

要从命令行转换巨大的文本文件,perl 让我这样做:

perl -pe < in.txt > out.txt

但这本质上是逐行的。偶尔,我想在多行的东西上进行匹配。

如何在命令行中执行此操作?

【问题讨论】:

  • 我确信 Perl 可以满足您的需求。您可以要求它使用换行符以外的记录分隔符,或者它可以将文件拆分为空行或使用固定的记录大小。或者,如果您的文件大小合理,您可以将其全部读入内存并从那里处理。除非您详细解释您的应用程序,否则我不知道什么是最好的方法
  • 具体来说,perl -0777 -pe ... 本质上不是逐行的。 :)
  • 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是题外话,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,请描述问题以及迄今为止为解决该问题所做的工作。

标签: regex perl multiline command-line-tool


【解决方案1】:

要 slurp 文件而不是逐行处理,请使用 -0777 开关:

perl -0777 -pe 's/.../.../g' in.txt > out.txt

perlrun #Command Switches 中所述:

特殊值 -00 将导致 Perl 在段落模式下 slurp 文件。 -0400 或以上的任何值都会导致 Perl 读取整个文件,但按照惯例,值 -0777 是通常用于此目的的值。

显然,对于大文件,这可能无法正常工作,在这种情况下,您需要编写某种类型的缓冲区来进行此替换。虽然没有关于您意图的真实信息,但我们无法提供更好的建议。

【讨论】:

    【解决方案2】:

    跨越线的边界

    所以你想跨行边界 grep...

    您很可能已经安装了pcregrep。您可能知道,PCRE 代表Perl-Compatible Regular Expressions,该库绝对是 Perl 风格的,尽管与 Perl 不同。

    多行匹配,需要开启多行模式-M,和(?m)不一样

    运行pcregrep -M "(?s)^b.*\d+" text.txt

    在这个文本文件上:

    a
    b
    c11
    

    输出将是

    b
    c11
    

    而 grep 将返回空。

    摘自文档:

    -M, --multiline 允许模式匹配多于一行。当给出这个选项时,模式可能有用地包含文字换行符 ^ 和 $ 字符的演员和内部出现。输出 对于成功的匹配,可能包含不止一行,最后一行 其中是比赛结束的那一场。如果匹配的字符串 以换行符结束输出在该行的末尾结束。

    设置此选项时,PCRE 库在“多行”中调用 模式。可以匹配的行数是有限制的, pcregrep 在扫描时缓冲输入文件的方式 它。但是,pcgrep 确保至少 8K 字符或其余字符 文件(以较短者为准)可用于 前向匹配,类似地,前 8K 个字符(或所有 前面的字符,如果少于 8K)保证是 可用于后向断言。此选项在以下情况下不起作用 输入是逐行读取的(参见--line-buffered。)

    【讨论】:

    • 这听起来像我想要的,除了我还需要替换部分。
    猜你喜欢
    • 2012-03-25
    • 1970-01-01
    • 1970-01-01
    • 2021-06-23
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多