繁体   English   中英

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

[英]Combining two different multi-row strings into one using Perl

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

TMS: xxxxxxx11110000

TDI: xxxxxxx00001111

TMS: xxxx00001111

TDI:xxxx11110000

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

0
0
0
0
1
1
1
1

然后我在文件中搜索“TDI:”并重复相同的过程。 最后一步是将第一个字符串与第二个字符串连接以获得以下 output (给定上面的示例):

01
01
01
01
10
10
10
10

10
10
10
10
01
01
01
01

但是,当我连接这两个字符串时,我现在得到的 output 是

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 命令等,但没有任何运气。

最好有一个最小的例子来看看你是如何解决这个问题的。 此外,您的输入文件还有很多不清楚的地方。 例如, TMSTDI是否总是在文件中配对,或者您必须检查吗? 您是否总是将下一个TDI实例与前面的TMS事件配对,或者它们可以更加脱节? TMS总是先于TDI还是可以逆转?

假设数据看起来就像您在示例中指出的那样,执行此操作的一种简单方法可能是读取每一行并将数据存储在一个用于TMS字符串的数组和一个用于TDI字符串的数组中。 If both arrays are full, then we have a pair to output, so output the pair and clear the arrays for the next events. 否则,读取下一行以获取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

Output 将是:

01
01
01
01
10
10
10
10

10
10
10
10
01
01
01
01

您想要的是 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 的输入,要么首先将结果放入数组中,要么拆分输入字符串。

hobbs 来自Code Golf 的回答:激光解决了一个完全不同的问题,但部分解决方案是关于如何“旋转”多线字符串,它在这里可能很有用。

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

$_ = '0000111111110000
1111000000001111';

现在执行以下代码:

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

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

输入:

$_ = '0000111111110000
1111000000001111';

Output:

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

该算法很容易推广到输入中的任意数量的行和列。

输入:

$_='ABCDE
12345
FGHIJ
67890';

Output:

A1F6
B2G7
C3H8
D4I9
E5J0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM