Frage

Wie mache ich ein diff von zwei Strings oder Arrays in Ruby?

War es hilfreich?

Andere Tipps

Für Arrays, verwenden Sie den Minus-Operator. Zum Beispiel:

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

Hier ist die letzte Zeile entfernt alles von foo, die auch in Goo ist, so dass nur das Element 1. Ich weiß nicht, wie dies für zwei Strings zu tun, aber bis jemand, der Beiträge über sie weiß, könnte man einfach jede konvertieren String in ein Array, verwenden Sie den minus-Operator, und dann das Ergebnis zurück zu konvertieren.

habe ich mit dem Fehlen einer guten Bibliothek für diese in Ruby frustriert, also schrieb ich http: // GitHub. com / SAMG / Diffy . Es verwendet diff unter der Decke, und konzentriert sich auf seinem bequem und ziemlich Ausgabeoptionen.

Für Strings, würde ich zuerst das Ruby-Gem versuchen, dass @ sam-Safran unten erwähnt. Es ist einfacher zu installieren: 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

Die HTMLDiff dass @ DA01 Nennungen oben für mich gearbeitet.

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

Sieht ziemlich gut. Durch die Art und Weise habe ich dies mit dem acts_as_audited Plugin.

Es gibt auch diff-lcs, die als Juwel zur Verfügung steht. Es hat sich seit 2004 nicht aktualisiert worden, aber haben wir es ohne Probleme im Einsatz.

Edit:. Eine neue Version im Jahr 2011 veröffentlicht wurde Sieht aus wie es wieder in der aktiven Entwicklung ist

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

t=s2.chars; s1.chars.map{|c| c == t.shift ? c : '^'}.join

Diese einfache Linie gibt einen ^ in den Positionen, die nicht übereinstimmen. Das ist oft genug und es ist copy / paste-fähig.

Ich habe gerade ein neues Projekt, das sehr flexibel scheint:

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

Der Versuch, es aus und versuchen, irgendeine Art von Bericht zu veröffentlichen.

Ich hatte den gleichen Zweifel und die Lösung fand ich nicht 100% Rubin, aber ist das Beste für mich. Das Problem mit diff.rb ist, dass es kein schönes Formatierer haben, die Diffs in einem humanisierten Weg zu zeigen. So habe ich diff von dem O mit diesem 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

Just zum Nutzen von Windows Menschen: Diffy sieht brillant, aber ich glaube es wird nur auf * nix arbeiten (korrigiert mich wenn ich falsch liege). Sicherlich hat es nicht auf meinem Rechner arbeiten.

ein Vergnügen für mich Differ gearbeitet (Windows 7 x64 Ruby 1.8.7).

Um zeichenweise Auflösung zu erhalten habe ich eine neue Funktion Damerau-levenshtein gem

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"]

oder mit Analyse:

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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top