Domanda

Come faccio a fare una differenza di due stringhe o array in Ruby?

È stato utile?

Altri suggerimenti

Per gli array, utilizzare l'operatore meno.Per esempio:

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

Qui l'ultima riga rimuove da foo tutto ciò che è anche in goo, lasciando solo l'elemento 1.Non so come farlo per due stringhe, ma finché qualcuno che lo conosce non pubblica un post a riguardo, potresti semplicemente convertire ogni stringa in un array, utilizzare l'operatore meno e quindi riconvertire il risultato.

Ero frustrato dalla mancanza di una buona libreria per questo in Ruby, quindi ho scritto http://github.com/samg/diffy.Utilizza diff sotto le coperte e si concentra sulla comodità e sulla fornitura di graziose opzioni di output.

Per gli archi, proverei prima il Ruby Gem menzionato da @sam-saffron di seguito.È più facile da installare: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

L'HTMLDiff menzionato da @ da01 sopra ha funzionato per 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; }

Sembra piuttosto buono.A proposito, l'ho usato con il acts_as_audited collegare.

C'è anche diff-lcs che è disponibile come gemma. Non è stato aggiornato dal 2004 ma lo stiamo usando senza alcun problema.

Modificare: Una nuova versione è stata rilasciata nel 2011.Sembra che sia tornato in fase di sviluppo attivo.

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

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

Questa semplice riga dà a ^ nelle posizioni che non corrispondono.È abbastanza spesso ed è copiabile/incollabile.

Ho appena trovato un nuovo progetto che sembra abbastanza flessibile:

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

Provandolo e proverò a pubblicare una sorta di rapporto.

Avevo lo stesso dubbio e la soluzione che ho trovato non è ruby ​​al 100%, ma per me è la migliore.Il problema con diff.rb è che non ha un bel formattatore, per mostrare le differenze in modo umanizzato.Quindi ho usato diff dal sistema operativo con questo codice:

 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

Solo a beneficio degli utenti Windows:diffy sembra geniale ma credo che funzionerà solo su *nix (correggimi se sbaglio).Certamente non ha funzionato sulla mia macchina.

Differ ha funzionato a meraviglia per me (Windows 7 x64, Ruby 1.8.7).

Per ottenere la risoluzione carattere per carattere ho aggiunto una nuova funzione a gemma di damerau-levenshtein

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

o con l'analisi:

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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top