【问题标题】:How do I match across newlines in a perl regex?如何在 perl 正则表达式中匹配换行符?
【发布时间】:2012-12-05 08:18:55
【问题描述】:

我正在尝试解决如何使用 perl(来自 shell)来匹配换行符。以下:

(echo a b c d e; echo f g h i j; echo l m n o p) | perl -pe 's/(c.*)/[$1]/'

我明白了:

a b [c d e]
f g h i j
l m n o p

这是我所期望的。但是当我在我的正则表达式末尾放置一个/s 时,我得到了这个:

a b [c d e
]f g h i j
l m n o p

我期望并希望它打印的是这样的:

a b [c d e
f g h i j
l m n o p
]

是我的正则表达式有问题,还是我的 perl 调用标志有问题?

【问题讨论】:

  • 我认为,使用/s 应该可以完成这项工作。但是,您也可以使用[\S\s]* 代替.*
  • @Rohit Jain:不够:他正在使用 -p 开关调用 Perl,因此需要启用 slurp 模式。

标签: regex perl shell


【解决方案1】:

-p 逐行循环输入,其中“行”由输入记录分隔符$/ 分隔,默认为换行符。如果你想将所有的 STDIN 插入到 $_ 中进行匹配,请使用 -0777

$ echo "a b c d e\nf g h i j\nl m n o p" | perl -pe 's/(c.*)/[$1]/s'
a b [c d e
]f g h i j
l m n o p
$ echo "a b c d e\nf g h i j\nl m n o p" | perl -0777pe 's/(c.*)/[$1]/s'
a b [c d e
f g h i j
l m n o p
]

有关这两个标志的信息,请参阅Command Switches in perlrun-l (dash-ell) 也很有用。

【讨论】:

  • 比较 perl -MO=Deparse -0e1perl -MO=Deparse -0777e1。更改了您的代码以使用后者。
  • 这完全有效,而且对于我的实际用例而不是这个人为的例子也是如此。干杯 :-) 让我不必在 Ruby 中编写自定义的东西。
【解决方案2】:

问题是你的单行代码一次只工作一行,你的正则表达式很好:

use strict;
use warnings;
use 5.014;

my $s = qq|a b c d e
f g h i j
l m n o p|;

$s =~ s/(c.*)/[$1]/s;

say $s;

【讨论】:

    【解决方案3】:

    其实你的单线是这样的:

    while (<>) {
    
         $ =~ s/(c.*)/[$1]/s;
    }
    

    这意味着正则表达式仅适用于您输入的第一行。

    【讨论】:

      【解决方案4】:

      有不止一种方法可以做到这一点:既然你“一次阅读整个文件”,我个人会删除 -p 修饰符,明确地吞下整个输入,然后从那里开始:

      echo -e "a b c d e\nf g h i j\nl m n o p" | perl -e '$/ = undef; $_ = <>; s/(c.*)/[$1]/s; print;'
      

      这个解决方案确实有更多的字符,但对于其他读者来说可能更容易理解(三个月后你会是;-D)

      【讨论】:

        【解决方案5】:

        您一次阅读一行,那么您认为它怎么可能匹配跨越多行的内容?

        添加-0777 将“行”重新定义为“文件”(不要忘记添加/s 以使. 匹配换行符)。

        $ (echo a b c d e; echo f g h i j; echo l m n o p) | perl -0777pe's/(c.*)/[$1]/s'
        a b [c d e
        f g h i j
        l m n o p
        ]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多