分割一个ruby字符串或数组

时间:2021-06-26 21:45:23

How do I do a diff of two strings or arrays in Ruby?

如何在Ruby中处理两个字符串或数组的差值?

11 个解决方案

#1


20  

diff.rb is what you want, which is available at http://users.cybercity.dk/~dsl8950/ruby/diff.html via internet archive:

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

http://web.archive.org/web/20140421214841/http:/ / users.cybercity.dk:80 / ~ dsl8950 / ruby / diff.html

#2


30  

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 that is also in goo, leaving just the element 1. I don't know how to do this for two strings, but until somebody who knows posts about it, you could just convert each string to an array, use the minus operator, and then convert the result back.

在这里,最后一行从foo中删除所有也在goo中的元素,只留下元素1。我不知道如何处理两个字符串,但除非有人知道它,你可以把每个字符串转换成一个数组,使用负号运算符,然后把结果转换回来。

#3


21  

I got frustrated with the lack of a good library for this in ruby, so I wrote http://github.com/samg/diffy. It uses diff under the covers, and focuses on being convenient, and providing pretty output options.

我对ruby中缺少一个好的库感到失望,所以我写了http://github.com/samg/diffy。它在封面下使用diff,并注重方便,并提供漂亮的输出选项。

#4


18  

For strings, I would first try out the Ruby Gem that @sam-saffron mentioned below. It's easier to install: http://github.com/pvande/differ/tree/master

对于字符串,我将首先尝试下面提到的@sam-saffron的Ruby Gem。更容易安装:http://github.com/pvande/difference /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


5  

The HTMLDiff that @da01 mentions above worked for me.

上面@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; }

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

看起来很好。顺便说一下,我使用的是acts_as_audited插件。

#6


5  

There is also diff-lcs which is available as a gem. It hasn't been updated since 2004 but we have been using it without any problem.

也有扩散-lcs作为一种宝石可用。它从2004年开始就没有更新过,但是我们一直在使用它,没有任何问题。

Edit: A new version was released in 2011. Looks like it's back in active development.

编辑:新版本于2011年发布。看起来它又回到了积极的发展中。

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

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

#7


2  

I just found a new project that seems pretty flexible:

我刚发现一个新项目,看起来很灵活:

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

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

Trying it out and will try to post some sort of report.

试一试,然后试着发布一些报告。

#8


2  

I had the same doubt and the solution I found is not 100% ruby, but is the best for me. The problem with diff.rb is that it doesn't have a pretty formatter, to show the diffs in a humanized way. So I used diff from the OS with this code:

我也有同样的疑问,我找到的解决方案不是100% ruby,但对我来说是最好的。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

#9


2  

Just for the benefit of Windows people: diffy looks brilliant but I belive it will only work on *nix (correct me if I'm wrong). Certainly it didn't work on my machine.

只是为了Windows用户的利益:diffy看起来很聪明,但我相信它只适用于*nix(如果我错了请纠正我)。当然在我的机器上不能用。

Differ worked a treat for me (Windows 7 x64, Ruby 1.8.7).

对我来说,不同(Windows 7 x64, Ruby 1.8.7)是一种享受。

#10


1  

Maybe Array.diff via monkey-patch helps...

也许数组。diff通过monkey-patch帮助……

http://grosser.it/2011/07/07/ruby-array-diffother-difference-between-2-arrays/

http://grosser.it/2011/07/07/ruby-array-diffother-difference-between-2-arrays/

#11


0  

To get character by character resolution I added a new function to damerau-levenshtein gem

为了通过字符分辨率获得字符,我在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"]

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

#1


20  

diff.rb is what you want, which is available at http://users.cybercity.dk/~dsl8950/ruby/diff.html via internet archive:

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

http://web.archive.org/web/20140421214841/http:/ / users.cybercity.dk:80 / ~ dsl8950 / ruby / diff.html

#2


30  

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 that is also in goo, leaving just the element 1. I don't know how to do this for two strings, but until somebody who knows posts about it, you could just convert each string to an array, use the minus operator, and then convert the result back.

在这里,最后一行从foo中删除所有也在goo中的元素,只留下元素1。我不知道如何处理两个字符串,但除非有人知道它,你可以把每个字符串转换成一个数组,使用负号运算符,然后把结果转换回来。

#3


21  

I got frustrated with the lack of a good library for this in ruby, so I wrote http://github.com/samg/diffy. It uses diff under the covers, and focuses on being convenient, and providing pretty output options.

我对ruby中缺少一个好的库感到失望,所以我写了http://github.com/samg/diffy。它在封面下使用diff,并注重方便,并提供漂亮的输出选项。

#4


18  

For strings, I would first try out the Ruby Gem that @sam-saffron mentioned below. It's easier to install: http://github.com/pvande/differ/tree/master

对于字符串,我将首先尝试下面提到的@sam-saffron的Ruby Gem。更容易安装:http://github.com/pvande/difference /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


5  

The HTMLDiff that @da01 mentions above worked for me.

上面@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; }

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

看起来很好。顺便说一下,我使用的是acts_as_audited插件。

#6


5  

There is also diff-lcs which is available as a gem. It hasn't been updated since 2004 but we have been using it without any problem.

也有扩散-lcs作为一种宝石可用。它从2004年开始就没有更新过,但是我们一直在使用它,没有任何问题。

Edit: A new version was released in 2011. Looks like it's back in active development.

编辑:新版本于2011年发布。看起来它又回到了积极的发展中。

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

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

#7


2  

I just found a new project that seems pretty flexible:

我刚发现一个新项目,看起来很灵活:

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

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

Trying it out and will try to post some sort of report.

试一试,然后试着发布一些报告。

#8


2  

I had the same doubt and the solution I found is not 100% ruby, but is the best for me. The problem with diff.rb is that it doesn't have a pretty formatter, to show the diffs in a humanized way. So I used diff from the OS with this code:

我也有同样的疑问,我找到的解决方案不是100% ruby,但对我来说是最好的。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

#9


2  

Just for the benefit of Windows people: diffy looks brilliant but I belive it will only work on *nix (correct me if I'm wrong). Certainly it didn't work on my machine.

只是为了Windows用户的利益:diffy看起来很聪明,但我相信它只适用于*nix(如果我错了请纠正我)。当然在我的机器上不能用。

Differ worked a treat for me (Windows 7 x64, Ruby 1.8.7).

对我来说,不同(Windows 7 x64, Ruby 1.8.7)是一种享受。

#10


1  

Maybe Array.diff via monkey-patch helps...

也许数组。diff通过monkey-patch帮助……

http://grosser.it/2011/07/07/ruby-array-diffother-difference-between-2-arrays/

http://grosser.it/2011/07/07/ruby-array-diffother-difference-between-2-arrays/

#11


0  

To get character by character resolution I added a new function to damerau-levenshtein gem

为了通过字符分辨率获得字符,我在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"]

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