my $s = ' ABC: 123 xyz: 100 def: YYY aaa: ZZZ';;
my %hash = $s =~ m[(\S+)\s*:\s*(\S+)]g;;
print %hash;;
ABC 123 def YYY aaa ZZZ xyz 100
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
That looks way too complicated. Try this:
my $s = ' ABC: 123 xyz: 100 def: YYY aaa: ZZZ';
my %hash= ($s=~/([^ :]+)/g);
| [reply] [d/l] |
This is brilliant.... but what exactly is going on here?
| [reply] |
Hello alphacoorg, and welcome to the Monastery!
$s=~/([^ :]+)/g
The square brackets create a bracketed character class and the initial ^ (caret) negates what follows, so this character class matches any character other than a space or a colon. The + quantifier means one or more, and the surrounding parentheses create a capture group. Finally,
the /g modifier creates a global match, and since the expression is evaluated in list context, the global match returns a list of matches.
That is, the regular expression returns a list of the substrings in ' ABC: 123 xyz: 100 def: YYY aaa: ZZZ' that do not contain space or colon characters:
("ABC", 123, "xyz", 100, "def", "YYY", "aaa", "ZZZ")
(You can verify this yourself by assigning the output of the regular expression to an array instead of a hash, and then printing out the array.)
In Perl, assigning a list to a hash populates the hash with key/value pairs taken in sequence from the list. So in this case, the hash is created with entries:
"ABC" => 123, "xyz" => 100, etc.
(Note that Perl’s “fat comma” =>, which is what you normally use when assigning key/value pairs to a hash, is really just an ordinary comma, functioning as a list separator, with the additional property that the expression on its left-hand side is turned into a string.)
Hope that helps,
| [reply] [d/l] [select] |
$ perl -wl
use String::Escape qw( string2hash hash2string );
use Data::Dumper;
my $string = hash2string( ( foo => 1, bar => 2, tze => 3 ) );
print $string;
my %hash = string2hash( $string );
print Dumper \%hash;
__END__
foo=1 bar=2 tze=3
$VAR1 = {
'bar' => '2',
'foo' => '1',
'tze' => '3'
};
--
No matter how great and destructive your problems may seem now, remember, you've probably only seen the tip of them. [1]
| [reply] [d/l] |
As is often the case with Perl, you can cheat. :)
#!/usr/bin/perl -w
use strict;
my $a = " a: b c: d e: f ";
$a =~ y/://d;
my %h = eval "qw/$a/"; # The Evil String Eval
print "Key [$_] | Value [$h{$_}]\n" for keys %h;
--
Human history becomes more and more a race between education and catastrophe. -- HG Wells
| [reply] [d/l] |
my $s = ' ABC: 123 xyz: 100 def: YYY aaa: ZZZ';
my %hash;
for (split /[^:]\s+/, $s) {
my ($key, $val) = split /:\s*/;
next unless $key;
$hash{$key} = $val;
}
| [reply] [d/l] |
use strict;
use warnings;
use Data::Dumper;
my $s = q{ ABC: 123 xyz: 100 def: YYY aaa: ZZZ};
my %extract =
map { split m{\s*:\s*} }
split m{(?<!:)\s+}, $s;
print Data::Dumper->Dumpxs( [ \ %extract ], [ q{*extract} ] );
This produces
%extract = (
'ABC' => '123',
'def' => 'YYY',
'aaa' => 'ZZZ',
'xyz' => '100'
);
I hope this is of interest. Cheers, JohnGG | [reply] [d/l] [select] |
Aside from the solution...the main problem here is you're trying to cram so much into single lines that you don't know what's going on. Slow down a little, especially when things aren't working. | [reply] |