PERL如何将字符串分组不在同一行中

时间:2012-04-24 07:12:33

标签: perl

内部文本文件

Letter A = "AAA"
Letter B = "BBB"

我试试:

perl -p -e 's/(Letter A \=)(.*\")(\n+)(Letter B \=)/$1$2$3$4/g' text

但它不起作用。问题似乎发生在\n之后。

有什么想法吗?

其实我想交换一下这些话,我们怎么能这样做呢? 来源:
字母A =“AAA”
字母B =“BBB”
要:
字母A =“BBB”
字母B =“AAA”

如果两行之间有其他单词。还有其他解决方案吗?

ABCABC
字母A =“BBB”
字母B =“AAA”
DSAAS
TRQWTR
字母C =“DDD”
字母D =“CCC”
SDAGER
LPITET

3 个答案:

答案 0 :(得分:6)

-p将输入拆分为行,这意味着您的模式永远不会在任何地方看到\n,而是在它正在查看的文本的末尾。如果要进行多行匹配,则需要编写实际脚本或更改输入记录分隔符,以使其不在行上分割(可能-0777使用“slurp”模式)。

perl -0777 -p -e 's/(Letter A =)(.*")(\n+)(Letter B =)/$1 Hello$2$3$4 Hello/' test2
Letter A = Hello "AAA"
Letter B = Hello "BBB"

答案 1 :(得分:0)

如果你把它放到一个小程序中,你可以做这样的事情。顶部注释掉的部分表明它适用于多对线。我建立它的方式,你必须管文本文件。

# my $text = qq~Letter A = "AAA"
# Letter B = "BBB"
# Letter C = "CCC"
# Letter D = "DDD"~;
# 
# my @temp = split /\n/, $text;
my @temp = <>;

for (my $i=0; $i <= $#temp; $i+=2) {
  $temp[$i] =~ m/"(\w+)"/;
  my $w1 = $1;
  $temp[$i+1] =~ s/"(\w+)"/"$w1"/;
  my $w2 = $1;
  $temp[$i] =~ s/"$w1"/"$w2"/;
}
print join "\n", @temp;

输出:

Letter A = "BBB"
Letter B = "AAA"
Letter C = "DDD"
Letter D = "CCC"

如果中间可能存在其他行,则代码必须如此。

my $text = qq~Letter A = "AAA"
testtesttest
Letter B = "BBB"
loads 
of text
Letter C = "CCC"
Letter D = "DDD"
Letter E = "EEE"

Letter F = "FFF"~;

my @temp = split /\n/, $text;
# my @temp = <>;

my $last_index; # use this to remember where the last 'fist line' was
for (my $i=0; $i <= $#temp; $i+=1) {
  if (!defined $last_index) {
    # if we have not find a 'first line' yet, look if this is it
    $last_index = $i if $temp[$i] =~ m/"(\w+)"/;
  } elsif ($temp[$i] =~ m/"(\w+)"/) {
    # otherwhise if we already have a 'first line', check if this is a 'second line'
    $temp[$last_index] =~ m/"(\w+)"/; # use the 'first line'
    my $w1 = $1; 
    $temp[$i] =~ s/"(\w+)"/"$w1"/; # and the current line
    my $w2 = $1;
    $temp[$last_index] =~ s/"$w1"/"$w2"/;
    $last_index = undef; # remember to reset the 'first line'
  }
}
print join "\n", @temp;

输出:

Letter A = "BBB"
testtesttest
Letter B = "AAA"
loads 
of text
Letter C = "DDD"
Letter D = "CCC"
Letter E = "FFF"

Letter F = "EEE"

答案 2 :(得分:-1)

我认为你需要这个。试试吧

perl -pe 's/$\\n/Hello/g' filename

<强>输出

[tethomas@~/Perl]cat t
Letter A = "AAA"
Letter B = "BBB"
[tethomas@~/Perl]perl -pe 's/$\\n/Hello/g' t
Letter A = "AAA"HelloLetter B = "BBB"Hello