We're sorry Aspose doesn't work properply without JavaScript enabled.

Free Support Forum - aspose.com

Word正则替换如何正确使用

我使用了以下的代码,测试正则替换,但结果只替换了一个,请问如何替换全部? 谢谢了!

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)

@hzjianglf,

请尝试使用以下代码。 希望这可以帮助。

Document doc = new Document("E:\\testtravel\\testtravel.docx");
DocumentBuilder builder = new DocumentBuilder(doc);

Pattern regex = Pattern.compile("\\{(.*?)\\}", Pattern.CASE_INSENSITIVE);

FindReplaceOptions opts = new FindReplaceOptions();
opts.setDirection(FindReplaceDirection.BACKWARD);
opts.setReplacingCallback(new ReplaceTextWithFieldHandler("MERGEFIELD"));

doc.getRange().replace(regex, "", opts);

doc.save("E:\\testtravel\\awjava-19.4.docx");

@awais.hafeez
非常感谢!完美解决!