Разделить массив элементов, разделенных символом «.» - PullRequest
0 голосов
/ 03 июня 2019

Я пытаюсь прочитать ниже содержимое файла CSV построчно в Perl.

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

A7777777.A777777777.XXX3604,XXX,3604,YES,9
B9694396.B216905785.YYY0018,YYY,0018,YES,13
C9694396.C216905785.ZZZ0028,ZZZ,0028,YES,16

Я могу разбить содержимое строки, используя приведенный ниже код, а также могу проверить содержимое:

@column_fields1 = split(',', $_);   
print $column_fields1[0],"\n";

Я также пытаюсь найти вторую часть в первом столбце файла CSV (т. Е. A777777777 или B216905785 или C216905785 ) - первый столбец, ограниченный . с использованием приведенного ниже кода, и я не могу его получить.

Вместо этого печатается только новая строка.

my ($v1, $v2, $v3) = split(".", $column_fields1[0]);
print $v2,"\n";

Может кто-нибудь подсказать, как разбить элемент массива и получить указанное выше значение?

Что касается моей функциональности, мне нужно где-то первое значение столбца где-то, а где-то только вторая часть.

Ниже мой код:

use strict;
use warnings;

my $dailybillable_tab_section1_file = "./sql/demanding_01_T.csv";
open(FILE, $dailybillable_tab_section1_file) or die "Could not read from $dailybillable_tab_section1_file, program halting.";

my @column_fields1;
my @column_fields2;

while (<FILE>) 
{
    chomp;
    @column_fields1 = split(',', $_);

    print $column_fields1[0],"\n";

    my ($v1, $v2, $v3) = split(".",$column_fields1[0]);
    print $v2,"\n";

    if($v2 ne 'A777777777')
        {
        …
        …
        …
    }
    else
    {
        …
        …
        …

    }

}
close FILE;

Ответы [ 2 ]

2 голосов
/ 03 июня 2019

split принимает регулярное выражение в качестве первого аргумента. Вы можете передать ему строку (как в вашем коде), но содержимое строки будет просто интерпретировано как регулярное выражение во время выполнения.

Это не проблема для , (что не имеет особого значения в регулярном выражении), но оно разрывается с . (что соответствует любому (не символу новой строки) символа в регулярном выражении).

Ваша попытка решить проблему с split "\." не удалась, потому что "\." идентичен ".": обратный слеш имеет свое обычное значение экранирования строки, но, поскольку . не является особенным в строках, экранирование не имеет эффект. Это можно увидеть, просто напечатав полученную строку:

print "\.\n";  # outputs '.', same as print ".\n";

То, что . затем интерпретируется как регулярное выражение, вызывает проблемы, которые вы наблюдали.

Обычное решение - просто передать регулярное выражение в split:

split /\./, $string

Теперь обратная косая черта интерпретируется как часть регулярного выражения, заставляя . буквально совпадать.

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

split "\\.", $string

Первая обратная косая черта экранируется от второй обратной косой черты, давая строку из двух символов (\.), которая при интерпретации как регулярное выражение означает то же самое, что и /\./.

1 голос
/ 03 июня 2019

Если вы посмотрите документацию для split(), вы увидите, что она дает следующие способы вызова функции:

split / PATTERN /, EXPR,LIMIT

split / PATTERN /, EXPR

split / PATTERN /

split

В трех из этих примеров первый аргументфункция /PATTERN/.То есть split() ожидает, что ему будет предоставлено регулярное выражение, которое определяет, как входная строка разбивается на части.

Очень важно понимать, что этот аргумент является регулярным выражением, а не строкой.К сожалению, парсер Perl не настаивает на этом.Это позволяет вам использовать первый аргумент, который выглядит как строка (как вы сделали).Но как бы это ни выглядело, это не строка.Это регулярное выражение.

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

split(".",$COLUMN_FIELDS1[0])

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

split(/\./, $COLUMN_FIELDS1[0])

Обновление: Это общепринято среди программистов Perlэта переменная с именами в верхнем регистре является константой и не меняет своих значений.Используя имена в верхнем регистре для стандартных переменных, вы, вероятно, перепутаете следующего человека, который редактирует ваш код (который может стать вами через шесть месяцев).

...