[英]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 命令等,但没有任何运气。
最好有一个最小的例子来看看你是如何解决这个问题的。 此外,您的输入文件还有很多不清楚的地方。 例如, TMS
和TDI
是否总是在文件中配对,或者您必须检查吗? 您是否总是将下一个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.