読者です 読者をやめる 読者になる 読者になる

謎言語使いの徒然

適当に気になった技術や言語を流すブログ。

google_diff_match_patch

日記 Java OSS

Google 先生で採用している Diff ライブラリ。

https://code.google.com/p/google-diff-match-patch/

jar 配布なしで、ソースでの提供です。Apache2 ライセンスなので、安心して使えますね。

各種言語で可能な限り同じ使い勝手を想定しているのか、命名規則が snake case だったりするのですが、まぁご愛嬌でしょう。

使ってみた

安心のコピペ可能ソースをぺたり。

  • Specs2
  • Scala2.10.x
  • sbt13.0 の環境で動作確認

注意、デフォルトパッケージ名からパッケージを移動してます。

後は知らん。

package utils.models

import org.specs2.mutable.Specification
import scala.collection.JavaConversions._


class DiffMatchPatch extends Specification {

  val base =
    """
      |# The first chapter.
      |Non editable line.
      |Updating first point.
      |The second edit point.
      |Conflicted edit point.
      |First chapter end.
    """.stripMargin

  val updateFirst =
    """
      |# The first chapter.
      |Non editable line.
      |Update first.
      |The second edit point.
      |Conflicted: updated by first changeset.
      |First chapter end.
      |
      |# The Second Chapter By First Change set.
      |
      |This message is created with first change set.
      |Is diff_match_patch's coding rule are best way?
    """.stripMargin

  "Diff match patch" should {
    "Get difference with updateFirst" in {
      val diff = new diff_match_patch()
      val lines = diff.diff_linesToChars(base, updateFirst)
      val (text1, text2, lineArray) = (lines.chars1, lines.chars2, lines.lineArray)
      val result = diff.diff_main(text1, text2, false)
      diff.diff_charsToLines(result, lineArray)

      result.foreach(v =>
        println("%s  %s".format(v.operation, v.text))
      )
      true
    }
  }
}

実行結果

EQUAL  
# The first chapter.
Non editable line.

DELETE  Updating first point.

INSERT  Update first.

EQUAL  The second edit point.

DELETE  Conflicted edit point.

INSERT  Conflicted: updated by first changeset.

EQUAL  First chapter end.

INSERT  
# The Second Chapter By First Change set.

This message is created with first change set.
Is diff_match_patch's coding rule are best way?

EQUAL      

尚、diff_linesToChars を使わずに呼び出すと、単語どころか、愚直に全部の差分を洗ってくるので注意が必要。

個人的に行比較だけ出来れば問題ないのでここはスルーしてみた。