次の文字列があります。
$str = "list
XYZ
status1 : YES
value1 : 100
status2 : NO
value2 : 200
Thats all";
この文字列を入力として受け取り、たとえばキーと値status1
としてハッシュを返す関数を使用して、それをハッシュに変換したいと思います。YES
その方法は?
そして、返されたハッシュを参照する方法は?
いつものように、それを行うには複数の方法があります。5人来ました。
これが一番かっこいいと思います。正規表現は、ハッシュを初期化したいリストとまったく同じすべてのキャプチャのリストを返します。
my %regex = $str =~ /(\S+)\s*:\s*(\S+)/g;
これは、ほとんどのプログラマーにとって最も簡単な方法だと思います。
my @lines = split /\R/ => $str;
my %iterative = ();
for (@lines) {
next unless /(\S+)\s*:\s*(\S+)/;
$iterative{$1} = $2;
}
ここで説明することは何もありません。最初split
に文字列を行単位で処理し、次にそれらを反復処理して、のように見えない行を除外しますfoo : bar
。終わり。
すべてを大きなリスト式として書くのは少しハックに感じますが、何かを表現する方法をもっと学ぶには興味深いかもしれません。
my %list = map { /(\S+)\s*:\s*(\S+)/ and $1 => $2 }
grep { /:/ }
split /\R/ => $str;
右から左に読む: 上記の例のように、文字列を行単位で分割することから始めます。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;
これは、空白の分離のみに正規表現を使用した面白いものです。状態を追跡する必要があります。
# 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;
}
}
楽しみのために(memoweのいずれかを使用することをお勧めします)、YAMLを(ab)使用するものを次に示します。
#!/usr/bin/env perl
use strict;
use warnings;
use YAML;
my $str = "list
XYZ
status1 : YES
value1 : 100
status2 : NO
value2 : 200
Thats all";
$str = join "\n", grep { /:/ } split "\n", $str;
my $hash = Load "$str\n";
#!/usr/bin/perl
use warnings;
$\="\n";
sub convStr {
my $str = $_[0];
my %h1=();
while ($str =~m/(\w+)\s+:\s+(\w+)/g) {
$h1{$1} =$2;
}
return \%h1;
}
my $str = "list
XYZ
status1 : YES
value1 : 100
status2 : NO
value2 : 200
Thats all";
my $href=convStr($str);
foreach (keys(%$href)) {
print $_ , "=>", $href->{$_};
}
これを実行すると、次のようになります。
status2=>NO
value1=>100
status1=>YES
value2=>200
my %hhash;
my @lines = split /\s+\n/, $str;
foreach (@lines)
{
$_=~s/^\s+//g;
if(/:/)
{
$key=(split(/:/))[0];
$value=(split(/:/))[1];
$hhash{$key}=$value;
}
}