Как я могу разбить строку на части по два символа в каждой в Perl?

Как мне взять строку в Perl и разбить ее на массив с записями длиной в два символа каждая?

Я попытался это:

@array = split(/../, $string);

но не получил ожидаемых результатов.

В конечном итоге я хочу превратить что-то вроде этого

F53CBBA476

в массив, содержащий

F5 3C BB A4 76

person Jax    schedule 16.12.2008    source источник


Ответы (4)


@array = ( $string =~ m/../g );

Оператор сопоставления с образцом ведет себя особым образом в контексте списка в Perl. Он обрабатывает операцию итеративно, сопоставляя шаблон с остатком текста после предыдущего совпадения. Затем формируется список из всего текста, совпавшего при каждом применении сопоставления с образцом.

person Bill Karwin    schedule 16.12.2008

Если вам действительно нужно использовать split, вы можете сделать:

grep {length > 0} split(/(..)/, $string);

Но я думаю, что самый быстрый способ будет с unpack :

unpack("(A2)*", $string);

Оба этих метода имеют «преимущество» в том, что если строка имеет нечетное количество символов, то последний будет выведен сам по себе.

person mat    schedule 16.12.2008
comment
Поскольку похоже, что он работает с шестнадцатеричными символами, так что это немного спорный вопрос, но A работает только для символов ASCII. Разделение должно работать для любой кодировки, но вы можете добавить /s к регулярному выражению, чтобы \n соответствовало .. - person Chas. Owens; 29.04.2009
comment
Должно быть a2, а не A2. Бывшие полосы удаляют пробелы, которые в лучшем случае излишни. - person ikegami; 19.05.2011

На самом деле, чтобы поймать нечетный символ, вы хотите сделать второй символ необязательным:

@array = ( $string =~ m/..?/g );
person ChrisD    schedule 16.12.2008
comment
да, но это намного медленнее, чем распаковка. - person mat; 17.12.2008

Шаблон, переданный в split, определяет, что отделяет то, что вам нужно. Если вы хотите использовать разделение, вы должны использовать что-то вроде

my @pairs = split /(?(?{ pos() % 2 })(?!))/, $string;

or

my @pairs = split /(?=(?:.{2})+\z)/s, $string;

Это довольно плохие решения. Лучшие решения включают в себя:

my @pairs = $string =~ /..?/sg;  # Accepts odd-length strings.

my @pairs = $string =~ /../sg;

my @pairs = unpack '(a2)*', $string;
person ikegami    schedule 19.05.2011
comment
Привет @ikegami, есть ли способ разделить эту строку на 4 части так, чтобы 1-я 2-я часть содержала по 2 символа в каждой, а последние 2 части - по 3 символа в каждой... т.е. F5 3C BBA 476 - person Bhagyesh Dudhediya; 04.04.2018