diff рубиновая строка или массив - PullRequest
54 голосов
/ 17 сентября 2008

Как мне сделать diff из двух строк или массивов в Ruby?

Ответы [ 12 ]

32 голосов
/ 17 сентября 2008

Для массивов используйте оператор минус. Например:

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

Здесь последняя строка удаляет из foo все, что также есть в goo, оставляя только элемент 1. Я не знаю, как сделать это для двух строк, но пока кто-то, кто знает сообщения об этом, вы можете просто преобразовать каждый строка в массив, используйте оператор минус, а затем конвертируйте результат обратно.

22 голосов
/ 30 июня 2010

Я был разочарован отсутствием хорошей библиотеки для этого в ruby, поэтому я написал http://github.com/samg/diffy. Он использует diff под обложками и фокусируется на удобстве и предоставлении симпатичных опций вывода.

20 голосов
/ 17 сентября 2008

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

19 голосов
/ 06 января 2009

Для строк я сначала попробую Ruby Gem, который @ sam-saffron упоминал ниже Проще установить: 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
5 голосов
/ 11 апреля 2009

HTMLDiff, который @ da01 упоминает выше, работал для меня.

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.

5 голосов
/ 07 января 2009

Существует также diff-lcs, который доступен как драгоценный камень. Он не обновлялся с 2004 года, но мы использовали его без проблем.

Редактировать: Новая версия была выпущена в 2011 году. Похоже, она снова в активной разработке.

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

3 голосов
/ 26 июля 2018
t=s2.chars; s1.chars.map{|c| c == t.shift ? c : '^'}.join

Эта простая строка дает ^ в позициях, которые не совпадают. Этого достаточно, и он может копировать / вставлять.

2 голосов
/ 03 февраля 2012

Только для пользы Windows: diffy выглядит великолепно, но я верю, что он будет работать только на * nix (поправьте меня, если я ошибаюсь). Конечно, это не сработало на моей машине.

Разница работала для меня (Windows 7 x64, Ruby 1.8.7).

2 голосов
/ 03 октября 2009

У меня были те же сомнения, и решение, которое я нашел, не на 100% рубиновое, а лучшее для меня. Проблема с diff.rb в том, что у него нет симпатичного средства форматирования, чтобы показать различия в гуманизированной форме. Поэтому я использовал diff из ОС с этим кодом:

 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 голосов
/ 31 июля 2009

Я только что нашел новый проект, который кажется довольно гибким:

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

Попробуй и попробуй опубликовать какой нибудь отчет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...