2010-04-20 3 views
6

Обычной «Perlism» генерирует список как-то перебрать в таком виде:Можно ли использовать распаковку для разбиения строки на символы в Perl?

for($str=~/./g) { print "the next character from \"$str\"=$_\n"; }

В этом случае глобальный матча регулярное выражение возвращает список, который один символ в своей очереди, из строки $str, и присваивает это значение $_

Вместо регулярных выражений, split может использоваться таким же образом или 'a'..'z', map и т.д.

Я в vestigating unpack для генерации поля по интерпретации поля строки. Я всегда находил unpack, чтобы быть менее простым в отношении того, как работает мой мозг, и я никогда не очень глубоко его врывал в него.

Как простой случай, я хочу создать список, который является одним символом в каждом элементе из строки, используя распаковку (да - я знаю, что могу сделать это с split(//,$str) и /./g, но я действительно хочу посмотреть, может ли распаковка используйте этот способ ...)

Очевидно, что я могу использовать список полей для распаковки, то есть unpack("A1" x length($str), $str), но есть ли другой способ, который похож на globbing? т.е. я могу позвонить unpack(some_format,$str) либо в контексте списка, либо в цикле, так что unpack вернет следующую группу символов в группе формата до тех пор, пока не будет превышена $ str?

Я прочитал The Perl 5.12 Pack pod и Perl 5.12 pack tutorial и the Perkmonks tutorial

Вот пример кода:

#!/usr/bin/perl 
use warnings; 
use strict; 

my $str=join('',('a'..'z', 'A'..'Z')); #the alphabet... 

$str=~s/(.{1,3})/$1 /g;    #...in groups of three 
print "str=$str\n\n"; 

for ($str=~/./g) { 
print "regex: = $_\n"; 
} 

for(split(//,$str)) { 
print "split: \$_=$_\n"; 
} 

for(unpack("A1" x length($str), $str)) { 
print "unpack: \$_=$_\n"; 
} 

ответ

9

pack и unpack шаблоны могут использовать скобки для группировки вещей так же, как регэкспы может. За группой может следовать счетчик повторов. * как счетчик повторений означает «повторять до тех пор, пока вы не закончите вещи, чтобы упаковать/распаковать».

for(unpack("(A1)*", $str)) { 
    print "unpack: \$_=$_\n"; 
} 

Вам нужно будет запустить бенчмарк, чтобы узнать, какая из них самая быстрая.

+0

Я знал, что это должно быть просто! Теперь, когда я играю с ним, '' (A1) * "' будет glob (мой вопрос) и '' (A1) $ i "' будет генерировать поля $ i. Персиковый! Вы знаете, где это хорошо документировано? Большая часть материала в Интернете была невелика ... – dawg

+0

@drewk: в 'perldoc -f pack' (http://perldoc.perl.org/functions/pack.html) в разделе« Поставка * для повторного подсчета вместо числа означает использование, однако, осталось много элементов ... "и" A() -группа является суб-TEMPLATE, заключенным в круглые скобки ... " – Ether

+0

@ Другие: примеры в perldoc не говорили со мной в этом дело. Большинство использований '*' были в форме «сожрать остальное», как в 'unpack 'a3/A A *', '007 Bond J'; дает ('Bond', 'J') 'и я думаю, что perldoc на pack/unpack может быть ... более ясным ... – dawg