How do I split a string in Ruby?

I have special strings for example name1="value1" name2='value2'

. Values ​​can contain spaces and are delimited by single quotes or double quotes. The names never contain spaces. name / value pairs are separated by spaces.

I want to parse them into a list of name-value pairs like this

string.magic_split() => { "name1"=>"value1", "name2"=>"value2" }

      

If Ruby understood the statements I could make, I could do it with

string.split(/[\'\"](?=\s)/).each do |element|
    element =~ /(\w+)=[\'\"](.*)[\'\"]/
    hash[$1] = $2
end

      

but Ruby doesn't understand view-based views, so I'm somewhat stuck.

However, I am sure there are much more elegant ways to solve this problem anyway, so I turn to you. Do you have a good idea for solving this problem?

+2


source to share


5 answers


It doesn't fit with meanings like "hello," she said, but that might be enough.



str = %q(name1="value1" name2='value 2')
p Hash[ *str.chop.split( /' |" |='|="/ ) ]
#=> {"name1"=>"value1", "name2"=>"value 2"}

      

+6


source


This is not a complete answer, but Oniguruma , the standard regex library in 1.9, supports lookaround assertions. It can be installed like a gem if you are using Ruby 1.8.x.



However, and as Sorpigal commented, instead of using a regex, I would tend to iterate through the string one character at a time, keeping track of whether or not you are in the name part when you reach an equal sign, when you are in quotes and when you reach an agreed closing quote. When you reach the final quote, you can put the name and value in the hash and move on to the next entry.

+2


source


class String

  def magic_split
    str = self.gsub('"', '\'').gsub('\' ', '\'\, ').split('\, ').map{ |str| str.gsub("'", "").split("=") }
    Hash[str]
  end

end

      

+1


source


This should do it for you.

 class SpecialString
   def self.parse(string)
     string.split.map{|s| s.split("=") }.inject({}) {|h, a| h[a[0]] = a[1].gsub(/"|'/, ""); h }
   end
 end

      

+1


source


Try: /[='"] ?/

I don't know the Ruby syntax, but here is a Perl script you can translate

#!/usr/bin/perl 
use 5.10.1;
use warnings;
use strict;
use Data::Dumper;

my $str =  qq/name1="val ue1" name2='va lue2'/;

my @list = split/[='"] ?/,$str;
my %hash;
for (my $i=0; $i<@list;$i+=3) {
  $hash{$list[$i]} = $list[$i+2];
}
say Dumper \%hash;

      

Output:

$VAR1 = {
          'name2' => 'va lue2',
          'name1' => 'val ue1'
        };

      

0


source







All Articles