Diffライブラリを使って文字単位での差分
http://sweetbat.ddo.jp/miraque/で、投稿内容の異なる部分を色分けするようにしたいと思い文字単位でのDiff(差分)を抽出できるライブラリを探していました。
例)
元:あいうえおう
先:あいかえおう
ネットでいろいろ調べていると行単位や配列の差分抽出できるライブラリしかなくどうしようかと思ったんだけど、ものは考えようでした。
自分が考えたのは文字列を1文字づつ分割して配列にしてDiffライブラリをかまして、またくっつけるということです。
スマートなやり方かどうかはわからないけどそれで一応実現した。
自分のサイトは携帯サイトなので半角カナも考慮したソースになっていますが以下のようにしました。
package miraque.utils; import java.util.ArrayList; import java.util.List; public class DiffUtil { private String _moto; private String _saki; /** * コンストラクタ */ public DiffUtil() { _moto = ""; _saki = ""; } /** * コンストラクタ * * @param moto * @param saki */ public DiffUtil(String moto, String saki) { _moto = moto; _saki = saki; } /** * 差分を計算する */ public void exec() { String[] motosp = split(_moto); String[] sakisp = split(_saki); _moto = ""; _saki = ""; @SuppressWarnings("unchecked") List<Difference> differenceList = new Diff( motosp, sakisp ).diff(); for ( Difference o : differenceList ) { setcolor(o.getDeletedStart(), o.getDeletedEnd(), motosp); setcolor(o.getAddedStart(), o.getAddedEnd(), sakisp); } for (String s : motosp) { _moto += s; } for (String s : sakisp) { _saki += s; } } /** * 半角カタカナの濁点、半濁点を1文字として分割 * * @param str * @return */ private String[] split(String str) { List<String> arr = new ArrayList<String>(); for (int i=0; i < str.length(); i++) { String s = str.substring(i, i+1); String t=""; try { t = str.substring(i+1, i+2); } catch (Exception e) { ; } if ("゙".equals(t) || "゚".equals(t)) { s = str.substring(i, i+2); i++; } arr.add(s); } return arr.toArray(new String[0]); } /** * 差分部分を赤色に変更 * * @param start * @param end * @param sp */ private void setcolor(int start, int end, String[] sp) { if (sp.length > start && end != -1) { sp[start] = "<font color=\"RED\">" + sp[start]; sp[end] = sp[end] + "</font>"; } } /** * @return _moto */ public String getMoto() { return _moto; } /** * @return _saki */ public String getSaki() { return _saki; } }
参考ページ
http://d.hatena.ne.jp/reiro/20080225/javadiff
id:reiro:20080225#javadiff