使用Perl将两个不同的多行字符串合并为一个

时间:2019-10-25 18:02:19

标签: perl

在对那些字符串执行正则表达式操作之后,试图将两个多行字符串合并为一个字符串时遇到了一些问题。例如,我以这种形式的数据开始:

TMS:xxxxxxx11110000

TDI:xxxxxxx00001111

TMS:xxxx00001111

TDI:xxxx11110000

要以我需要的形式获取它,我在文件中搜索关键字“ TMS:”,仅提取数据,使用正则表达式删除“ x”,反转数据,然后将每个位放在自己的一行并将其存储在字符串中。结果字符串如下所示:

0
0
0
0
1
1
1
1

然后,我在文件中搜索“ TDI:”并重复相同的过程。最后一步是将第一个字符串与第二个字符串连接起来,以得到以下输出(鉴于上面的示例):

01
01
01
01
10
10
10
10

10
10
10
10
01
01
01
01

但是,当我连接两个字符串时,我现在作为输出得到的是

0
0
0
0
1
1
1
1
1
1
1
1
0
0
0
0

1
1
1
1
0
0
0
0
0
0
0
0
1
1
1
1 

是否可以在不对过程进行太多更改的情况下获得所需的结果?我试过使用split命令,chomp命令等,但没有任何运气。

3 个答案:

答案 0 :(得分:1)

最好有一个简单的示例,看看您如何解决此问题。此外,关于输入文件还有很多不清楚的地方。例如,TMSTDI是否始终在文件中配对,还是必须检查?您是否总是将下一个TDI实例与前面的TMS事件配对,还是可以使其更脱节? TMS始终位于TDI之前还是可以颠倒?

一种简单的方法是,假设数据看起来像示例中所示,可能是读取每一行并将数据存储在TMS字符串的一个数组中,并将数据存储在一个数组中。 TDI字符串。如果两个数组都已满,则需要一对输出,因此输出该对并清除数组以备下一个事件使用。否则,请阅读下一行以获取TDI数据:

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

my (@first, @second);
while (my $elem = <DATA>) {
    ($elem =~ /^TMS/)
        ? (@first = read_string($elem))
        : (@second = read_string($elem));
    if (@second) {
        for my $index (0..$#first) {
            print "$first[$index]$second[$index]\n";
        }
        print "\n";
        @first = @second = ();
    }
}

sub read_string {
    my $string = shift;
    my @bits = grep {/\d/} split('', $string);
    return reverse(@bits);
}


__DATA__
TMS: xxxxxxx11110000
TDI: xxxxxxx00001111
TMS: xxxx00001111
TDI: xxxx11110000

此输出将是:

01
01
01
01
10
10
10
10

10
10
10
10
01
01
01
01

答案 1 :(得分:1)

您想要的是一个zip操作。方便地List::MoreUtils为您提供了一个。

@x = qw/a b c d/;
@y = qw/1 2 3 4/;

# returns [a, 1], [b, 2], [c, 3], [d, 4]
@z = zip6 @x, @y;         

要获取zip的输入,请首先将结果放入数组中,或者拆分输入字符串。

答案 2 :(得分:0)

来自Code Golf: Lasers

hobbs答案正在解决一个完全不同的问题,但是部分解决方案是关于如何“旋转”多行字符串,在这里可能很有用。

首先,不要将每个位放在自己的行上,只需将不同行上不同输入行的位分开即可。将多行字符串放入$_

$_ = '0000111111110000
1111000000001111';

现在执行以下代码:

$_ = do {
    my $o;
    $o .= "\n" while s/^./$o.=$&,""/meg;
    $o };

(霍布斯算法中的替换以s/.$/.../开始。通过使用s/^./.../,它成为用于转置而不是旋转的算法)

输入:

$_ = '0000111111110000
1111000000001111';

输出:

01
01
01
01
10
10
10
10
10
10
10
10
01
01
01
01

该算法可以轻松地将其推广到输入中任意数量的行和列。

输入:

$_='ABCDE
12345
FGHIJ
67890';

输出:

A1F6
B2G7
C3H8
D4I9
E5J0