字符串逐字对比,标记出不同的部分

这里借用了commons-text包下的StringsComparator类来实现。首先引入依赖:

<dependency>
  <groupId>org.apache.commons</groupId>
  <artifactId>commons-text</artifactId>
  <version>1.10.0</version>
</dependency>

接下来编写工具类:

package com.xxx;

import lombok.Data;
import org.apache.commons.text.diff.CommandVisitor;
import org.apache.commons.text.diff.EditScript;
import org.apache.commons.text.diff.StringsComparator;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: zdf @Date: 2023/3/31 11:06:33 @Description:
 */
public class TextComparer {

  public static List<Difference> compare(String source, String compareTo) {
    StringsComparator comparator = new StringsComparator(source, compareTo);
    EditScript<Character> script = comparator.getScript();

    MyCommandsVisitor myCommandsVisitor = new MyCommandsVisitor();
    script.visit(myCommandsVisitor);
    myCommandsVisitor.finish();

    List<Difference> differenceList = myCommandsVisitor.getDifferenceList();

    return differenceList;
  }

  @Data
  private static class MyCommandsVisitor implements CommandVisitor<Character> {

    List<Difference> differenceList = new ArrayList<>();

    int deleteIndex = 0;
    int insertIndex = 0;

    boolean lastIsDelete = false;
    boolean lastIsInsert = false;

    int continueDeleteLen = 0;
    int continueInsertLen = 0;

    @Override
    public void visitDeleteCommand(Character character) {
      lastIsInsert = false;

      if (continueInsertLen > 0) {
        differenceList.add(
            new Difference(
                Difference.INSERTED, insertIndex - continueInsertLen, continueInsertLen));
        continueInsertLen = 0;
      }

      if (lastIsDelete) {
        continueDeleteLen++;
      } else {
        continueDeleteLen = 1;
        lastIsDelete = true;
      }

      deleteIndex++;
    }

    @Override
    public void visitInsertCommand(Character character) {
      lastIsDelete = false;

      if (continueDeleteLen > 0) {
        differenceList.add(
            new Difference(Difference.DELETED, deleteIndex - continueDeleteLen, continueDeleteLen));
        continueDeleteLen = 0;
      }

      if (lastIsInsert) {
        continueInsertLen++;
      } else {
        continueInsertLen = 1;
        lastIsInsert = true;
      }

      insertIndex++;
    }

    @Override
    public void visitKeepCommand(Character character) {
      lastIsInsert = false;
      lastIsDelete = false;

      if (continueInsertLen > 0) {
        differenceList.add(
            new Difference(
                Difference.INSERTED, insertIndex - continueInsertLen, continueInsertLen));
        continueInsertLen = 0;
      }

      if (continueDeleteLen > 0) {
        differenceList.add(
            new Difference(Difference.DELETED, deleteIndex - continueDeleteLen, continueDeleteLen));
        continueDeleteLen = 0;
      }

      deleteIndex++;
      insertIndex++;
    }

    public void finish() {
      if (continueInsertLen > 0) {
        differenceList.add(
            new Difference(
                Difference.INSERTED, insertIndex - continueInsertLen, continueInsertLen));
      }

      if (continueDeleteLen > 0) {
        differenceList.add(
            new Difference(Difference.DELETED, deleteIndex - continueDeleteLen, continueDeleteLen));
      }
    }
  }
}
package com.xxx;

public class Difference {

  public static final int DELETED = 0x102;
  public static final int INSERTED = 0x103;

  private int type;
  private int index;
  private int len;

  public Difference() {
    super();
  }

  public Difference(int type, int index, int len) {
    super();
    this.type = type;
    this.index = index;
    this.len = len;
  }

  public int getType() {
    return type;
  }

  public void setType(int type) {
    this.type = type;
  }

  public int getIndex() {
    return index;
  }

  public void setIndex(int index) {
    this.index = index;
  }

  public int getLen() {
    return len;
  }

  public void setLen(int len) {
    this.len = len;
  }

  public String toString() {
    return (type == DELETED ? "-" : "+") + "[" + index + ", " + (index + len) + "]";
  }
}

对比效果展示:

其中展示效果可根据需求自定义 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值