Как разбить строки в одной части текстового файла иначе, чем в другой?- Perl - PullRequest
1 голос
/ 14 марта 2019

Я очень новичок в кодировании.

У меня есть данные в текстовом файле, отформатированном следующим образом:

#
PROPERTY_A: TEXT1
PROPERTY_B: UNIT1
#
PROPERTY_A: TEXT2
PROPERTY_B: UNIT2
#
#
1 2
3 4

Я хочу вывести его в виде таблицы:

TEXT1 TEXT2
UNIT1 UNIT2
1     2
3     4

Я понимаю, как читать текстовый файл в массив строк, а затем как использовать split () для разбора каждой строки и массива строк. Я хочу записать данные в таблицу со свойствами в качестве заголовков каждого столбца, поэтому мне нужно будет разбивать их, используя «:», пока я не прочту 2 последовательные строки с включенным хешем, а затем перейду к «» для разделения.

Использование этого кода дает мне бесконечный цикл, который не возвращает никакого значения, даже если оба отдельных разбиения работают нормально.

my $dataAsText = SomeFunction->Run($imputDocument);
for (my $ln = 0; < $dataAsText->Lines->Count; ++$ln;)
my $line = $dataAsText->Lines($ln)
do {
   my @words = split ($line, ‘: ‘, 2);
   # then pass @words[1] to the first or second row of each column
} until ($line eq ‘#’ && $line + 1 eq ‘#’);
   my @words = split ($line, ‘ ‘);
   # then pass each @words values to its corresponding column
}

Как мне написать фрагмент кода, чтобы проверить наличие 2 последовательных строк с символами хеша, а затем изменить способ разделения строк перед их отправкой в ​​массивы?

Просто, чтобы уточнить, что окончательный документ данных может иметь сотни тысяч строк для чтения, это пример структуры.

Ответы [ 2 ]

1 голос
/ 15 марта 2019

Вы можете попробовать командную строку Perl

perl -F: -ane ' if(not /^\d+/) { $x.=$F[1] if not /^#/ } else { $y.=$_ } 
    END { $x=~s/\s*(\S+)\s*(\S+)\s*(\S+)\s*(\S+)/$1 $3\n$2 $4/gs; print $x,$y }' file

с вашими данными ввода:

$ cat marPar.txt
#
PROPERTY_A: TEXT1
PROPERTY_B: UNIT1
#
PROPERTY_A: TEXT2
PROPERTY_B: UNIT2
#
#
1 2
3 4

$ perl -F: -ane ' if(not /^\d+/) { $x.=$F[1] if not /^#/ } else { $y.=$_ } 
      END { $x=~s/\s*(\S+)\s*(\S+)\s*(\S+)\s*(\S+)/$1 $3\n$2 $4/gs; print $x,$y }' marPar.txt
TEXT1 TEXT2
UNIT1 UNIT2
1 2
3 4

$
0 голосов
/ 15 марта 2019

Нечто подобное должно делать.Что вы хотите сделать, это обнаружить строки, начинающиеся с хеша, и посчитать их;когда вы видите два подряд, поменяйте местами шаблон, который вы используете для разделения.

{
  # Inside a block so only the sub here can see them.
  my $double_hash_seen;
  my $splitter = qr/:/;   # First split pattern
  my $last_was_hash;

  sub split_appropriately {
    my($line) = @_;
    if (/^#/) {
      if ($last_was_hash) {
        # Double hash, switch modes.
        $splitter = qr/ /;  # Second split pattern
        return;             # We don't split hash lines
      }
      # Last was not a hash, but this was.
      $last_was_hash = 1;  # One hash seen.
      return;              # Don't split the hash line
    }
    # This isn't a hash. Turn off "hash seen" and split
    # with appropriate current pattern.
    $last_was_hash = 0;
    split $splitter, $line;  # Will stay switched once it changes
  }
}

while(<DATA>) {
  my($first, $second) = split_appropriately($_);
  next unless defined $first;
  print "Part 1: $first\n";
  print "Part 2: $second\n";
}
__DATA__
#
PROPERTY_A: TEXT1
PROPERTY_B: UNIT1
#
PROPERTY_A: TEXT2
PROPERTY_B: UNIT2
#
#
1 2
3 4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...