我参考了这个帖子,来实现我的占位符替换,但是发生了报错
https://forum.aspose.com/t/aspose-words-replacement-text-in-wrong-place-when-using-ireplacingcallback/211935
我经过 debug 发现第二次进这个 IReplacingCallback 对应的 run 是我第一次进入后删除的 run,导致了报错,正常情况下我删除这个 run 后,下次 IReplacingCallback 就不应该再匹配这个删除的 run了,为什么会这样,代码如下
public class ReplaceTest {
private static final String ASPOSE_TAG_REGEX = "\\[(.*?)]";
public static void main(String[] args) throws Exception {
Document doc = new Document("aaa.docx");
FindReplaceOptions options = new FindReplaceOptions();
options.setReplacingCallback(new ReplaceTagsEvaluator());
doc.getRange().replace(Pattern.compile(ASPOSE_TAG_REGEX), "", options);
doc.save("out.docx");
}
private static Run splitRun(Run run, int position) throws Exception {
Run afterRun = (Run)run.deepClone(true);
afterRun.setText(run.getText().substring(position));
run.setText(run.getText().substring(0, position));
run.getParentNode().insertAfter(afterRun, run);
return afterRun;
}
static class ReplaceTagsEvaluator implements IReplacingCallback {
@Override
public int replacing(ReplacingArgs e) throws Exception {
Node currentNode = e.getMatchNode();
if (e.getMatchOffset() > 0) {
currentNode = splitRun((Run)currentNode, e.getMatchOffset());
}
ArrayList<Run> runs = new ArrayList<>();
int remainingLength = e.getMatch().group().length();
while (remainingLength > 0 &&
currentNode != null &&
currentNode.getText().length() <= remainingLength) {
runs.add((Run)currentNode);
remainingLength = remainingLength - currentNode.getText().length();
do {
currentNode = currentNode.getNextSibling();
} while (currentNode != null && currentNode.getNodeType() != NodeType.RUN);
}
if (currentNode != null && remainingLength > 0) {
splitRun((Run)currentNode, remainingLength);
runs.add((Run)currentNode);
}
DocumentBuilder builder = new DocumentBuilder((Document)e.getMatchNode().getDocument());
builder.moveTo(runs.get(0));
String match = e.getMatch().group();
System.out.println("Match is: " + match);
builder.write(e.getMatch().group(1));
e.setReplacement("");
for (Run run : runs) {
run.remove();
}
return ReplaceAction.SKIP;
}
}
}
文件如下
aaa.docx (13.1 KB)