是否有任何Java库可以接受两个字符串,并根据* nix diff命令返回带格式化输出的字符串?
e.g。喂入
test 1,2,3,4
test 5,6,7,8
test 9,10,11,12
test 13,14,15,16
和
test 1,2,3,4
test 5,6,7,8
test 9,10,11,12,13
test 13,14,15,16
作为输入,它会给你
test 1,2,3,4 test 1,2,3,4
test 5,6,7,8 test 5,6,7,8
test 9,10,11,12 | test 9,10,11,12,13
test 13,14,15,16 test 13,14,15,16
就像我将文件传递给diff -y expected actual
我发现了this question,它为一般库提供了一些很好的建议,可以为你提供编程输出,但我想要直接的字符串结果。
我可以直接调用diff
作为系统调用,但是这个特定的应用程序将在unix和windows上运行,我无法确定环境实际上是否有diff
可用。
答案 0 :(得分:14)
用于计算的DiffUtils库 差异,应用补丁,generationg Java中的并排视图
Diff Utils库是一个OpenSource 用于执行比较的库 文本之间的操作:计算 差异,应用补丁,生成 统一差异或解析它们, 生成差异输出以方便将来 显示(如并排视图) 等等。
构建此库的主要原因是 缺乏易于使用的库 你需要的所有常用的东西 使用diff文件。原来它 受到了JRCS图书馆的启发 漂亮的diff模块设计。
主要功能
- 计算两个文本之间的差异。
- 能够提供比普通ascci更多的东西。数组或任何类型的列表 实现hashCode()和equals() 正确的可以受到 差异化使用此库
- 使用给定的补丁修补和取消文本
- 解析统一差异格式
- 产生人类可读的差异
答案 1 :(得分:6)
我最后自己动手了。不确定它是否是最好的实现,并且它很丑陋,但它会通过测试输入。
它使用java-diff进行重度差异提升(任何apache公共StrBuilder和StringUtils而不是库存Java StringBuilder)
public static String diffSideBySide(String fromStr, String toStr){
// this is equivalent of running unix diff -y command
// not pretty, but it works. Feel free to refactor against unit test.
String[] fromLines = fromStr.split("\n");
String[] toLines = toStr.split("\n");
List<Difference> diffs = (new Diff(fromLines, toLines)).diff();
int padding = 3;
int maxStrWidth = Math.max(maxLength(fromLines), maxLength(toLines)) + padding;
StrBuilder diffOut = new StrBuilder();
diffOut.setNewLineText("\n");
int fromLineNum = 0;
int toLineNum = 0;
for(Difference diff : diffs) {
int delStart = diff.getDeletedStart();
int delEnd = diff.getDeletedEnd();
int addStart = diff.getAddedStart();
int addEnd = diff.getAddedEnd();
boolean isAdd = (delEnd == Difference.NONE && addEnd != Difference.NONE);
boolean isDel = (addEnd == Difference.NONE && delEnd != Difference.NONE);
boolean isMod = (delEnd != Difference.NONE && addEnd != Difference.NONE);
//write out unchanged lines between diffs
while(true) {
String left = "";
String right = "";
if (fromLineNum < (delStart)){
left = fromLines[fromLineNum];
fromLineNum++;
}
if (toLineNum < (addStart)) {
right = toLines[toLineNum];
toLineNum++;
}
diffOut.append(StringUtils.rightPad(left, maxStrWidth));
diffOut.append(" "); // no operator to display
diffOut.appendln(right);
if( (fromLineNum == (delStart)) && (toLineNum == (addStart))) {
break;
}
}
if (isDel) {
//write out a deletion
for(int i=delStart; i <= delEnd; i++) {
diffOut.append(StringUtils.rightPad(fromLines[i], maxStrWidth));
diffOut.appendln("<");
}
fromLineNum = delEnd + 1;
} else if (isAdd) {
//write out an addition
for(int i=addStart; i <= addEnd; i++) {
diffOut.append(StringUtils.rightPad("", maxStrWidth));
diffOut.append("> ");
diffOut.appendln(toLines[i]);
}
toLineNum = addEnd + 1;
} else if (isMod) {
// write out a modification
while(true){
String left = "";
String right = "";
if (fromLineNum <= (delEnd)){
left = fromLines[fromLineNum];
fromLineNum++;
}
if (toLineNum <= (addEnd)) {
right = toLines[toLineNum];
toLineNum++;
}
diffOut.append(StringUtils.rightPad(left, maxStrWidth));
diffOut.append("| ");
diffOut.appendln(right);
if( (fromLineNum > (delEnd)) && (toLineNum > (addEnd))) {
break;
}
}
}
}
//we've finished displaying the diffs, now we just need to run out all the remaining unchanged lines
while(true) {
String left = "";
String right = "";
if (fromLineNum < (fromLines.length)){
left = fromLines[fromLineNum];
fromLineNum++;
}
if (toLineNum < (toLines.length)) {
right = toLines[toLineNum];
toLineNum++;
}
diffOut.append(StringUtils.rightPad(left, maxStrWidth));
diffOut.append(" "); // no operator to display
diffOut.appendln(right);
if( (fromLineNum == (fromLines.length)) && (toLineNum == (toLines.length))) {
break;
}
}
return diffOut.toString();
}
private static int maxLength(String[] fromLines) {
int maxLength = 0;
for (int i = 0; i < fromLines.length; i++) {
if (fromLines[i].length() > maxLength) {
maxLength = fromLines[i].length();
}
}
return maxLength;
}
答案 2 :(得分:0)
Busybox有一个非常精简的差异实现,不应该很难转换为java,但你必须添加两列功能。
答案 3 :(得分:0)
http://c2.com/cgi/wiki?DiffAlgorithm我在Google上发现了这一点,它提供了一些很好的背景和链接。如果你关心的算法不仅仅是做项目,还有一本关于动态编程的基本算法的书或者只是一本书。算法知识总是很好:)
答案 4 :(得分:0)
您可以使用Apache Commons Text库来实现此目的。该库基于“ Eugene W. Myers的非常高效的算法”提供“ diff”功能。
这使您能够创建自己的访问者,以便您可以按所需的方式处理差异,并可以将其输出到控制台或HTML等。这是一篇使用Apache Commons Text遍历nice & simple example to output side by side diff in HTML format的文章库和简单的Java代码。