Perl从匹配的字符串中删除换行符

时间:2015-09-24 22:37:46

标签: regex perl

我正在尝试解析一些源文件,但我遇到了这个问题。我正在搜索匹配特定的字符串,其中包含"<<<"和">>>"在它,我试图删除所有换行符从它找到上述符号开始,直到它遇到第一个&#34 ;;"符号。任何帮助都感激不尽。

这就是我想要做的事情:

输入:

... lines of code 
func1 <<< abc, xyz >>> ( str1,
                         str2,
                         str3);
... lines of code

输出:

... lines of code
func1 <<< abc, xyz >>> (str1, str2, str3);
... lines of code

变量func1,abc,xyz,str1,str2,str3都可以变化。

提前致谢。

编辑:

这是我尝试过的,到目前为止它只打印与输入相同的模式。

while (<$fh>) { 
  if (/\<\<\<.*\>\>\>/) {
     while ($_ !~ /\)\s*\;/) {
           chomp $_;
           $_ = <$fh>;
     }
     print $_;
   }
 }

编辑2:

问题已经解决。见答案。

4 个答案:

答案 0 :(得分:3)

my @long, $end;
while (<>) {                               # read a line
  if (/<<<.*>>>/ .. ($end = /;/)) {        # if needs joining,
    s/^\s+|\s+$//g;                        # trim it
    push @long, $_;                        # add to list
    print join(' ', @long) . "\n" if $end; # paste and print if at end
  } else {                                 # if doesn't need joining,
    print;                                 # just print without changes
  }
}

答案 1 :(得分:0)

这应该有效:

perl -npe 'if (/<<<.*?>>>/../;/) { chomp unless /;/ }' filename

以下是它的作用:

  1. 遍历文件中的所有行(-n选项)
  2. 匹配(包括)<<<.*?>>>;之间的所有行,并从中删除换行符。对于包含;
  3. 的行,不会执行此操作
  4. 打印所有行(-p选项)

答案 2 :(得分:0)

假设我们正在谈论压缩包含<<<;的语句:

#!/usr/bin/perl
use strict;
use warnings;

while ( <DATA> ) {
    if ( m/<<</ .. m/\);$/ ) {
         s/\s+/ /g;
         s/;\s*$/;\n/g;
    }
    print;
}

__DATA__
... lines of code 
func1 <<< abc, xyz >>> ( str1,
                         str2,
                         str3);
... lines of code
  • 我们使用范围运算符来检测我们是否介于<<<\);$
  • 之间
  • 如果我们是,我们用单个空格替换空格和换行符。
  • 然后我们需要在;
  • 之后重新插入尾随换行符

输出:

... lines of code 
func1 <<< abc, xyz >>> ( str1,  str2,  str3);
... lines of code

答案 3 :(得分:-1)

好的,我得到了我做错的事。我试图在原地进行。我认为它的效率还不高,但确实有效。

编辑:决定不改变原作。使用来自@TLP的有用输入更改了代码

open my $fh, "<", $ARGV[0] or die "$!";
open my $out, ">", "output.out" or die "$!";
while (<$fh>)
{
    if (/\<\<\<.*\>\>\>/)
    {
        while (1)
        {
            if (/\)\s*\;/) { s/\s//g; last; }
            else {  s/\s//g;
                $_ .= <$fh>; }
        }
    }
    print $out $_."\n";
}

close $out;
close $fh;