package com.aspose.words.examples.programming_documents.find_replace; import java.awt.Color; import java.util.ArrayList; import java.util.regex.Pattern; import com.aspose.words.Document; import com.aspose.words.FindReplaceOptions; import com.aspose.words.IReplacingCallback; import com.aspose.words.Node; import com.aspose.words.NodeType; import com.aspose.words.ReplaceAction; import com.aspose.words.ReplacingArgs; import com.aspose.words.Run; import com.aspose.words.examples.Utils; public class FindAndHighlightText { private static final String dataDir = Utils.getSharedDataDir(FindAndHighlightText.class) + "FindAndReplace/"; public static void main(String[] args) throws Exception { Document doc = new Document(dataDir + "TestFile.doc"); FindReplaceOptions options = new FindReplaceOptions(); options.ReplacingCallback = new ReplaceEvaluatorFindAndHighlight(); options.setDirection(FindReplaceDirection.BACKWARD); // We want the "your document" phrase to be highlighted. Pattern regex = Pattern.compile("your document", Pattern.CASE_INSENSITIVE); doc.getRange().replace(regex, "", options); // Save the output document. doc.save(dataDir + "TestFile_out.doc"); } } class ReplaceEvaluatorFindAndHighlight implements IReplacingCallback { /** * This method is called by the Aspose.Words find and replace engine for * each match. This method highlights the match string, even if it spans * multiple runs. */ public int replacing(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 highlighting. 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); } // Now highlight all runs in the sequence. for (Run run : (Iterable<Run>) runs) run.getFont().setHighlightColor(Color.YELLOW); // Signal to the replace engine to do nothing because we have already done all what we wanted. return ReplaceAction.SKIP; } /** * Splits text of the specified run into two runs. Inserts the new run just * after the specified run. */ 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), (0) + (position))); run.getParentNode().insertAfter(afterRun, run); return afterRun; } }