Можно ли разделить содержимое файла после каждой 6. строки с помощью функции `split`? - PullRequest
1 голос
/ 21 октября 2019

Можно ли разделить содержимое файла после каждой строки 6. с помощью функции split?

Я пробовал разные шаблоны без успеха. Последнее:

split /(?=(?:.+$){6})/, $content;

В этом примере каждая 3. строка:

содержимое файла:

a1
a2
a3
b1
b2
b3
c1
c2
c3

результат после разделения:

a1
a2
a3,

b1
b2
b3,

c1
c2
c3

Ответы [ 2 ]

3 голосов
/ 21 октября 2019

Я бы не стал использовать регулярное выражение в ситуации, которую вы объяснили. Вместо этого просто посмотрите на количество строк, которые вы прочитали, и выведите все, что захотите, когда прочитаете правильное количество строк:

while( <DATA> ) {
    if( $. % 3 ) {  # $. is the line number for that filehandle
        print;
        }
    else {
        chomp;
        print $_, ",\n\n";
        }
    }

__DATA__
a1
a2
a3
b1
b2
b3
c1
c2
c3

Если ваше содержимое находится в скаляре в программе,вы можете открыть дескриптор файла в этом скаляре, чтобы вы могли использовать те же инструменты чтения файлов:

open my $string_fh, '<', \$content;

while( <$string_fh> ) {
    if( $. % 3 ) {  # $. is the line number for that filehandle
        print;
        }
    else {
        chomp;
        print $_, ",\n\n";
        }
    }

Превращение вещей в проблемы чтения файлов - это один из моих любимых приемов, и я показываю еще много способов сделать этовещи в Эффективное программирование на Perl . Например, если вы хотите также записать в строку вместо стандартного вывода, вы можете открыть дескриптор файла по скалярной ссылке:

open my $string_fh, '<', \$content;
open my $out_fh, '>', \(my $out);

while( <$string_fh> ) {
    if( $. % 3 ) {  # $. is the line number for that filehandle
        print {$out_fh} $_
        }
    else {
        chomp;
        print {$out_fh} $_, ",\n\n";
        }
    }

print $out;

Это позволяет легко переключаться между записью информации и обратно. в строке или записи в "настоящий" файловый дескриптор.

3 голосов
/ 21 октября 2019

Если предположить, что вопрос состоит в том, как разбить многострочную строку на подстроки из 6 строк, а затем использовать регулярное выражение с нулевой шириной, как в вопросе

/(?=(?:.+$){6})/m

(обратите внимание, что в вопросеМодификатор m отсутствовал) не может работать, так как он будет совпадать на каждом конце строки ($) (при условии, что последуют более шести строк) и, следовательно, будет разбивать строку в каждой строке. Нам нужно регулярное выражение, которое потребляет строки (а не утверждение нулевой ширины). Мы можем достичь этого, используя

/(?:^[^\n]+\n){6}/m

в качестве регулярного выражения-разделителя в split, а также сделать разделение возвратным разделителем, поместив регулярное выражение в скобках. Теперь split будет чередовать разделители со строками, расположенными между разделителями (которые в этом случае будут пустыми строками (так как разделители следуют друг за другом без символов между ними). ​​Чтобы избавиться от пустых строк, используйте grep:

my @res = grep {length} split /((?:^[^\n]+\n){6})/m, $content;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...