我有以下字符串:
$str = "list
XYZ
status1 : YES
value1 : 100
status2 : NO
value2 : 200
Thats all";
Run Code Online (Sandbox Code Playgroud)
我想用一个函数,它接受这个字符串作为输入,并返回一个散列把它转换成一个哈希status1作为密钥,并YES作为值的例子.
怎么办?
以及如何引用返回的哈希?
mem*_*owe 13
像往常一样,有不止一种方法可以做到这一点.这里有五个.
我认为这是最酷的一个.正则表达式返回所有捕获的列表,这正是我们要初始化散列的列表:
my %regex = $str =~ /(\S+)\s*:\s*(\S+)/g;
Run Code Online (Sandbox Code Playgroud)
对于大多数程序员来说,这是最简单的方法,我认为:
my @lines = split /\R/ => $str;
my %iterative = ();
for (@lines) {
next unless /(\S+)\s*:\s*(\S+)/;
$iterative{$1} = $2;
}
Run Code Online (Sandbox Code Playgroud)
这里没什么可解释的.我首先split是行中的字符串,然后迭代它们,留下看起来不像的行foo : bar.完成.
把所有内容写成一个大表单表达感觉有点hackish,但也许有趣的是学习更多表达方式:
my %list = map { /(\S+)\s*:\s*(\S+)/ and $1 => $2 }
grep { /:/ }
split /\R/ => $str;
Run Code Online (Sandbox Code Playgroud)
从右到左阅读:与上面的例子一样,我们首先将字符串拆分为行.grep过滤行:和最终地图中的行我使用键和值转换长度为2的列表中的匹配行字符串.
List :: Util的reduce函数的非平凡用例非常罕见.这是一个,基于上面的列表方法,返回一个哈希引用:
my $reduced = reduce {
$a = { $a =~ /(\S+)\s*:\s*(\S+)/ } unless ref $a;
$a->{$1} = $2 if $b =~ /(\S+)\s*:\s*(\S+)/;
return $a;
} grep { /:/ } split /\R/ => $str;
Run Code Online (Sandbox Code Playgroud)
这是一个有趣的,仅用于白色空间分离的正则表达式.它需要跟踪状态:
# preparations
my $state = 'idle';
my $buffer = undef;
my %state = ();
my @words = split /\s+/ => $str;
# loop over words
for my $word (@words) {
# last word was a key
if ($state eq 'idle' and $word eq ':') {
$state = 'got_key';
}
# this is a value for the key in buffer
elsif ($state eq 'got_key') {
$state{$buffer} = $word;
$state = 'idle';
$buffer = undef;
}
# remember this word
else {
$buffer = $word;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4381 次 |
| 最近记录: |