比较ruby串或数组

如何在Ruby中做两个string或数组的差异?

对于数组,使用减号运算符。 例如:

>> foo = [1, 2, 3] => [1, 2, 3] >> goo = [2, 3, 4] => [2, 3, 4] >> foo - goo => [1] 

这里最后一行删除了foo中的所有内容,只留下了元素1.我不知道如何为两个string做这个,但是直到有人知道这个string,你可以将每个string转换为数组,使用减号运算符,然后将结果转换回来。

我对Ruby的缺乏一个好的库感到沮丧,所以我写了http://github.com/samg/diffy 。 它使用diff的盖子,重点是方便,并提供漂亮的输出选项。

对于string,我会首先尝试下面提到的@sam-saffron的Ruby Gem。 安装更容易: http : //github.com/pvande/differ/tree/master

 gem install differ irb require 'differ' one = "one two three" two = "one two 3" Differ.format = :color puts Differ.diff_by_word(one, two).to_s Differ.format = :html puts Differ.diff_by_word(one, two).to_s 

@ da01上面提到的HTMLDiff为我工作。

 script/plugin install git://github.com/myobie/htmldiff.git # bottom of environment.rb require 'htmldiff' # in model class Page < ActiveRecord::Base extend HTMLDiff end # in view <h1>Revisions for <%= @page.name %></h1> <ul> <% @page.revisions.each do |revision| %> <li> <b>Revised <%= distance_of_time_in_words_to_now revision.created_at %> ago</b><BR> <%= Page.diff( revision.changes['description'][0], revision.changes['description'][1] ) %> <BR><BR> </li> <% end %> # in style.css ins.diffmod, ins.diffins { background: #d4fdd5; text-decoration: none; } del.diffmod, del.diffdel { color: #ff9999; } 

看起来不错。 顺便说一句,我用这个与acts_as_audited插件。

也有diff-lcs可以作为gem。 它从2004年以来一直没有更新,但我们一直在使用它没有任何问题。

编辑:在2011年发布了一个新的版本。看起来它回到了积极的发展。

http://rubygems.org/gems/diff-lcs

我刚刚find一个看起来非常灵活的新项目:

http://github.com/pvande/differ/tree/master

尝试一下,并会尝试发布某种报告。

我有同样的疑问,我发现的解决scheme不是100%的ruby,但对我来说是最好的。 diff.rb的问题是它没有一个漂亮的格式化器,以人性化的方式显示差异。 所以我使用这个代码从操作系统的差异:

  def diff str1, str2 system "diff #{file_for str1} #{file_for str2}" end private def file_for text exp = Tempfile.new("bk", "/tmp").open exp.write(text) exp.close exp.path end 

只是为了Windows用户的利益:diffy看起来很辉煌,但是我相信它只能在* nix上工作(如果我错了,请纠正我)。 当然,它不能在我的机器上工作。

不同的工作对我来说(Windows 7的X64,ruby1.8.7)。

为了逐字分辨我给damerau-levenshtein创造了一个新的function

 require "damerau-levenshtein" differ = DamerauLevenshtein::Differ.new differ.run "Something", "Smothing" # returns ["S<ins>o</ins>m<subst>e</subst>thing", # "S<del>o</del>m<subst>o</subst>thing"] 

或parsing:

 require "damerau-levenshtein" require "nokogiri" differ = DamerauLevenshtein::Differ.new res = differ.run("Something", "Smothing!") nodes = Nokogiri::XML("<root>#{res.first}</root>") markup = nodes.root.children.map do |n| case n.name when "text" n.text when "del" "~~#{n.children.first.text}~~" when "ins" "*#{n.children.first.text}*" when "subst" "**#{n.children.first.text}**" end end.join("") puts markup