Diff string or ruby ​​array

How do I make the difference of two strings or arrays in Ruby?

+49
ruby diff
Sep 17 '08 at 4:47
source share
11 answers
+20
Sep 17 '08 at 4:52
source share

For arrays, use the minus operator. For example:

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

Here, the last line removes everything from foo, which is also in goo, leaving only element 1. I don’t know how to do this for two lines, but for now, anyone who knows the messages about this, you can just convert each line to an array , use the minus operator, and then convert the result back.

+30
Sep 17 '08 at 4:53
source share

I was upset at the lack of a good library for this in ruby, so I wrote http://github.com/samg/diffy . It uses diff under covers and focuses on convenience and provides fairly accessible output options.

+21
Jun 30 '10 at 3:40
source share

For strings, I would first try the Ruby Gem that @ sam-saffron mentioned below. It is easier to install: 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 
+18
Jan 06 '09 at 11:11
source share

There is also diff-lcs , which is available as a gem. It has not been updated since 2004, but we used it without any problems.

Edit: In 2011, a new version was released. She looks in active development.

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

+5
Jan 07 '09 at 2:40
source share

The HTMLdiff that @ da01 mentions above worked for me.

 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; } 

Looks good. By the way, I used this with the acts_as_audited plugin.

+5
Apr 10 '09 at 23:32
source share

I just found a new project that looks pretty flexible:

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

Try this and try to publish some kind of report.

+2
Jul 31 '09 at 5:10
source share

I had the same doubt, and the solution I found was not 100% ruby, but better for me. The problem with diff.rb is that it does not have nice formatting to show the differences in a humanized way. So I used diff from the OS with this code:

  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 
+2
Oct 02 '09 at 21:27
source share

Just for Windows people: diffy looks brilliant, but I believe that it will only work on * nix (correct me if I'm wrong). Of course, this did not work on my machine.

The differential worked for me (Windows 7 x64, Ruby 1.8.7).

+2
Feb 03 '12 at 17:53
source share
+1
Jul 07 2018-11-11T00:
source share

To get the character by character resolution, I added a new damerau-levenshtein gem 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"] 

or with 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 
0
Aug 08 '17 at 15:28
source share



All Articles