比较ruby串或数组
如何在Ruby中做两个string或数组的差异?
diff.rb是你想要的,可以在 http://users.cybercity.dk/~dsl8950/ruby/diff.html 通过互联网存档:
http://web.archive.org/web/20140421214841/http://users.cybercity.dk:80/~dsl8950/ruby/diff.html
对于数组,使用减号运算符。 例如:
>> 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年发布了一个新的版本。看起来它回到了积极的发展。
我有同样的疑问,我发现的解决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)。
也许Array.diff通过猴子补丁帮助…
http://grosser.it/2011/07/07/ruby-array-diffother-difference-between-2-arrays/
为了逐字分辨我给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