İşte çok hızlı bir çözüm, genel bir bakışla yorumladı. (Uzunluğun için özür dilerim.) Temel olarak, bir sütun başlığı n'un başlangıcından sonra bir "sözcük" belirirse, n numaralı sütunun gövdesinin çoğunun gövdesi n + 1 sütununa girmediği sürece, Bu durumda bunun yerine orada biter. Bunu toplama, birden fazla farklı tabloyu desteklemek için genişletme, vb. Ayrıca, sütun başlığının sol ofseti dışında, merkez gibi bir sınır işareti veya sütun numarasıyla belirlenen bir değer olarak da kullanabilirsiniz.
#!/usr/bin/perl
use warnings;
use strict;
# Just plug your headers in here...
my @headers = ('Column One', 'Column Two', 'Column Three');
# ...and get your results as an array of arrays of strings.
my @result =();
my $all_headers = '(' . (join ').*(', @headers) . ')';
my $found = 0;
my @header_positions;
my $line = '';
my $row = 0;
push @result, [] for (1 .. @headers);
# Get lines from file until a line matching the headers is found.
while (defined($line = <DATA>)) {
# Get the positions of each header within that line.
if ($line =~ /$all_headers/) {
@header_positions = @-[1 .. @headers];
$found = 1;
last;
}
}
$found or die "Table not found! :<\n";
# For each subsequent nonblank line:
while (defined($line = <DATA>)) {
last if $line =~ /^$/;
push @{$_}, "" for (@result);
++$row;
# For each word in line:
while ($line =~ /(\S+)/g) {
my $word = $1;
my $position = $-[1];
my $length = $+[1] - $position;
my $column = -1;
# Get column in which word starts.
while ($column < $#headers &&
$position >= $header_positions[$column + 1]) {
++$column;
}
# If word is not fully within that column,
# and more of it is in the next one, put it in the next one.
if (!($column == $#headers ||
$position + $length < $header_positions[$column + 1]) &&
$header_positions[$column + 1] - $position <
$position + $length - $header_positions[$column + 1]) {
my $element = \$result[$column + 1]->[$row];
$$element .= " $word";
# Otherwise, put it in the one it started in.
} else {
my $element = \$result[$column]->[$row];
$$element .= " $word";
}
}
}
# Output! Eight-column tabs work best for this demonstration. :P
foreach my $i (0 .. $#headers) {
print $headers[$i] . ": ";
foreach my $c (@{$result[$i]}) {
print "$c\t";
}
print "\n";
}
__DATA__
This line ought to be ignored.
Column One Column Two Column Three
These lines are part of the tabular data to be processed.
The data are split based on how much words overlap columns.
This line ought to be ignored also.
Örnek çıktı:
Column One: These lines are The data are split
Column Two: part of the tabular based on how
Column Three: data to be processed. much words overlap columns.
sağlamak ve örnek verin. – DVK
Bir çözüm sağladım, ancak SIX sütunları üretecek. Bir sütun sütun ayırıcısı> 1 boşluk olması gereken bir varsayım mı yapıyorsunuz? – DVK
Hayır, ancak sütun başlık dizelerini bildiğimi ve sütun verilerinin üstbilgiler altında düzgün şekilde hizalandığını varsayabiliriz. – Thilo