我使用了以下的代码,测试正则替换,但结果只替换了一个,请问如何替换全部? 谢谢了!
public static void main(String[] args) throws Exception {
long startTime = System.currentTimeMillis();
if (!getLicense()) return;
Document doc = new Document("c:\\testtravel.docx");
DocumentBuilder builder = new DocumentBuilder(doc);
try {
//ByteArrayInputStream bais = new ByteArrayInputStream(templateText.getBytes());
//Document doc = new Document(bais);
//bais.close();
Pattern regex = Pattern.compile("\\{.*\\}", Pattern.CASE_INSENSITIVE);
doc.getRange().replace(regex, new ReplaceTextWithFieldHandler("MERGEFIELD"), false);
//deleteTableUseBookmarkAtFront(doc,"baseinfo");
doc.save("c:\\testtravel-out.docx");
System.out.println("ok");
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static class ReplaceTextWithFieldHandler implements IReplacingCallback {
public ReplaceTextWithFieldHandler(String name) {
mFieldName = name.toUpperCase();
}
public int replacing(ReplacingArgs e) throws Exception {
ArrayList runs = FindAndSplitMatchRuns(e);
// Create DocumentBuilder which is used to insert the field.
DocumentBuilder builder = new DocumentBuilder((Document) e.getMatchNode().getDocument());
builder.moveTo((Run) runs.get(runs.size() - 1));
// Insert the field into the document using the specified field type and the match text as the field name.
// If the fields you are inserting do not require this extra parameter then it can be removed from the string below.
System.out.println(e.getMatch().toString());
builder.write("12");
//builder.insertField(MessageFormat.format("{0} {1}", mFieldName, e.getMatch().group(0)));
// Now remove all runs in the sequence.
for (Run run : (Iterable<Run>) runs)
run.remove();
// Signal to the replace engine to do nothing because we have already done all what we wanted.
return ReplaceAction.SKIP;
}
/**
* Finds and splits the match runs and returns them in an ArrayList.
*/
public ArrayList FindAndSplitMatchRuns(ReplacingArgs e) throws Exception {
// This is a Run node that contains either the beginning or the complete match.
Node currentNode = e.getMatchNode();
// The first (and may be the only) run can contain text before the match,
// in this case it is necessary to split the run.
if (e.getMatchOffset() > 0)
currentNode = SplitRun((Run) currentNode, e.getMatchOffset());
// This array is used to store all nodes of the match for further removing.
ArrayList runs = new ArrayList();
// Find all runs that contain parts of the match string.
int remainingLength = e.getMatch().group().length();
while (
(remainingLength > 0) &&
(currentNode != null) &&
(currentNode.getText().length() <= remainingLength)) {
runs.add(currentNode);
remainingLength = remainingLength - currentNode.getText().length();
// Select the next Run node.
// Have to loop because there could be other nodes such as BookmarkStart etc.
do {
currentNode = currentNode.getNextSibling();
}
while ((currentNode != null) && (currentNode.getNodeType() != NodeType.RUN));
}
// Split the last run that contains the match if there is any text left.
if ((currentNode != null) && (remainingLength > 0)) {
SplitRun((Run) currentNode, remainingLength);
runs.add(currentNode);
}
return runs;
}
/**
* Splits text of the specified run into two runs.
* Inserts the new run just after the specified run.
*/
private 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;
}
private String mFieldName;
}
testtravel.zip (37.7 KB)