【问题标题】:How to split a string in Ruby?如何在 Ruby 中拆分字符串?
【发布时间】:2010-10-27 10:55:50
【问题描述】:

我有像name1="value1" name2='value2' 这样的特殊字符串。值可以包含空格,并由单引号或双引号分隔。名称从不包含空格。名称/值对由空格分隔。

我想将它们解析成这样的名称-值对列表

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

如果 Ruby 理解环视断言,我可以这样做

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

但是 Ruby 不理解环视断言,所以我有点卡住了。

但是,我确信无论如何都有更优雅的方法来解决这个问题,所以我求助于你。你有解决这个问题的好主意吗?

【问题讨论】:

  • 解析任何内容的唯一正确方法是一次一个字符。
  • 输入的字符串是标准格式吗?
  • @MarkThomas 值不能包含引号。输入字符串始终是字母数字。

标签: ruby regex string split


【解决方案1】:

这在“她说的“嗨”之类的值上失败了,但它可能已经足够好了。

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

【讨论】:

  • 很好,如果你改为 split( /' |" |='|="|'$|"$/ )
  • 哇,这是一个很酷的解决方案。谢谢!你能解释一下str之前的*是做什么的吗?
  • str.chop.split 的结果是一个数组。 *将此数组的元素转换成多个参数传递给Hash[]方法。
  • 有趣的是,我从未意识到 splat 运算符的优先级如此之低,以至于它会应用于整个表达式。
【解决方案2】:

这不是一个完整的答案,而是Oniguruma,1.9 中的标准正则表达式库支持环视断言。如果您使用的是 Ruby 1.8.x,它可以作为 gem 安装。

也就是说,正如Sorpigal 所评论的那样,当您到达等号时,我倾向于一次遍历字符串一个字符来跟踪您是否在名称部分,而不是使用正则表达式,当您在引号内并且达到匹配的结束引号时。在达到结束报价时,您可以将名称和值放入哈希中并继续下一个条目。

【讨论】:

  • Ruby on OSX 目前停留在 1.8.7。 (我知道我可以手动更新它,但我不想遇到与 XCode 工具等的兼容性问题。)
【解决方案3】:
class String

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

end

【讨论】:

    【解决方案4】:

    这应该为你做。

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

    【讨论】:

      【解决方案5】:

      试试看:/[='"] ?/

      我不懂 Ruby 语法,但这里有一个你可以翻译的 Perl 脚本

      #!/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;
      

      输出:

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

      【讨论】:

        猜你喜欢
        • 2011-04-25
        • 1970-01-01
        • 2011-04-29
        • 1970-01-01
        • 1970-01-01
        • 2015-08-09
        • 1970-01-01
        • 1970-01-01
        • 2013-08-08
        相关资源
        最近更新 更多