查找和替换

您可以使用键盘和鼠标轻松地在文档中导航,但如果您有许多页面要滚动,则需要相当长的时间才能在长文档中找到特定文本。 当您想要替换文档中使用的某些字符或单词时,这将更加耗时。 “查找和替换"功能使您能够在文档中查找字符序列,并将其替换为另一个字符序列。

Aspose.Words允许您在文档中查找特定的字符串或正则表达式模式,并将其替换为替代项,而无需安装和使用其他应用程序(如Microsoft Word)。 这将加快许多打字和格式化任务,可能节省您的工作时间。

本文介绍了如何在元字符的支持下应用字符串替换和正则表达式。

查找和替换 {#ways-to-find-and-replace}的方法

Aspose.Words提供了两种应用查找和替换操作的方法,方法如下:

  1. Simple string replacement-要查找并用另一个替换特定字符串,您需要指定一个搜索字符串(字母数字字符),该字符串将根据所有出现的情况用另一个指定的替换字符串替换。 两个字符串都不能包含符号。 请注意,字符串比较可能区分大小写,或者您可能不确定拼写或有几个类似的拼写。
  2. Regular expressions-指定正则表达式以查找精确的字符串匹配项,并根据正则表达式替换它们。 请注意,单词被定义为仅由字母数字字符组成。 如果只使用匹配的整个单词执行替换,并且输入字符串恰好包含符号,则不会找到短语。

此外,您还可以使用带有简单字符串替换和正则表达式的特殊元字符来指定查找和替换操作中的分隔符。

Aspose.Words使用IReplacingCallBack显示查找和替换功能。 您可以使用FindReplaceOptions类在查找和替换过程中使用许多选项。

使用简单字符串替换 {#find-and-replace-text-using-simple-string-replacement}查找和替换文本

您可以使用Replace方法之一来查找或替换特定字符串,并返回所做的替换数。 在这种情况下,您可以指定要替换的字符串、将替换其所有出现的字符串、替换是否区分大小写以及是否仅影响独立单词。

下面的代码示例演示如何查找字符串”CustomerName“并将其替换为字符串*“James Bond”*:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java
// Load a Word DOCX document by creating an instance of the Document class.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.writeln("Hello _CustomerName_,");
// Specify the search string and replace string using the Replace method.
doc.getRange().replace("_CustomerName_", "James Bond", new FindReplaceOptions());
// Save the result.
doc.save(dataDir + "Range.ReplaceSimple.docx");

在应用简单字符串替换之前,您可以注意到文档之间的差异:

before-simple-string-replacement-aspose-words-java

和应用简单的字符串替换后:

after-simple-string-replacement-aspose-words-java

使用正则表达式 {#find-and-replace-text-using-regular-expressions}查找和替换文本

正则表达式(regex)是描述特定文本序列的模式。 假设你想用一个单词的出现替换一个单词的所有双重出现。 然后,您可以应用以下正则表达式来指定双字模式:([a-zA-Z]+) \1

通过将Regex参数设置为正则表达式模式来查找匹配项,使用其他Replace方法来搜索和替换特定的字符组合。

下面的代码示例演示如何将匹配正则表达式模式的字符串替换为指定的替换字符串:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.writeln("sad mad bad");
if(doc.getText().trim() == "sad mad bad")
{
System.out.println("Strings are equal!");
}
// Replaces all occurrences of the words "sad" or "mad" to "bad".
FindReplaceOptions options = new FindReplaceOptions();
doc.getRange().replace(Pattern.compile("[s|m]ad"), "bad", options);
// Save the Word document.
doc.save(dataDir + "Range.ReplaceWithRegex.docx");

在使用正则表达式应用字符串替换之前,您可以注意到文档之间的差异:

before-replacement-with-regular-expressions-aspose-words-java

并用正则表达式应用字符串替换后:

after-replacement-with-regular-expressions-aspose-words-java

使用元字符 {#find-and-replace-text-using-metacharacters}查找和替换字符串

如果特定文本或短语由多个段落、部分或页面组成,则可以在搜索字符串或替换字符串中使用元字符。 一些元字符包括**&p**表示段落分隔符,**&b**表示分段分隔符,**&m**表示分页符,**&l**表示换行符。

下面的代码示例演示如何用段落和分页符替换文本:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.getFont().setName("Arial");
builder.writeln("First section");
builder.writeln(" 1st paragraph");
builder.writeln(" 2nd paragraph");
builder.writeln("{insert-section}");
builder.writeln("Second section");
builder.writeln(" 1st paragraph");
FindReplaceOptions options = new FindReplaceOptions();
options.getApplyParagraphFormat().setAlignment(ParagraphAlignment.CENTER);
// Double each paragraph break after word "section", add kind of underline and make it centered.
int count = doc.getRange().replace("section&p", "section&p----------------------&p", options);
// Insert section break instead of custom text tag.
count = doc.getRange().replace("{insert-section}", "&b", options);
doc.save(dataDir + "ReplaceTextContaingMetaCharacters_out.docx");

您可以使用HeaderFooter类在Word文档的页眉/页脚部分中查找和替换文本。

下面的代码示例演示如何替换文档中的标题部分的文本:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java
// Open the template document, containing obsolete copyright information in the footer.
Document doc = new Document(dataDir + "HeaderFooter.ReplaceText.doc");
// Access header of the Word document.
HeaderFooterCollection headersFooters = doc.getFirstSection().getHeadersFooters();
HeaderFooter header = headersFooters.get(HeaderFooterType.HEADER_PRIMARY);
// Set options.
FindReplaceOptions options = new FindReplaceOptions();
options.setMatchCase(false);
options.setFindWholeWordsOnly(false);
// Replace text in the header of the Word document.
header.getRange().replace("Aspose.Words", "Remove", options);
// Save the Word document.
doc.save(dataDir + "HeaderReplace.docx");

在应用标题字符串替换之前,您可以注意到文档之间的差异:

before-applying-header-string-replacement-aspose-words-java

并在应用标题字符串替换后:

after-applying-header-string-replacement-aspose-words-java

替换文档中页脚部分文本的代码示例与之前的页眉代码示例非常相似。 您需要做的就是替换以下两行:

HeaderFooter header = headersFooters.get(HeaderFooterType.HEADER_PRIMARY);
header.getRange().replace("Aspose.Words", "Remove", options);

与以下:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java
HeaderFooterCollection headersFooters = doc.getFirstSection().getHeadersFooters();
HeaderFooter footer = headersFooters.get(HeaderFooterType.FOOTER_PRIMARY);
// Replace text in the footer of the Word document.
int year = Calendar.getInstance().get(Calendar.YEAR);
footer.getRange().replace("(C) 2006 Aspose Pty Ltd.", "Copyright (C) " + year + " by Aspose Pty Ltd.", options);

在应用页脚字符串替换之前,您可以注意到文档之间的差异:

before-applying-footer-string-replacement-aspose-words-java

和应用页脚字符串替换后:

after-applying-footer-string-replacement-aspose-words-java

在查找和替换 {#ignore-text-during-find-and-replace}期间忽略文本

在应用查找和替换操作时,可以忽略文本的某些段。 因此,文本的某些部分可以从搜索中排除,并且查找和替换可以仅应用于其余部分。

Aspose.Words提供了许多用于忽略文本的查找和替换属性,例如IgnoreDeleted, IgnoreFieldCodes, IgnoreFields, IgnoreFootnotes, 和IgnoreInserted

下面的代码示例演示如何忽略删除修订版中的文本:

// Create new document.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
// Insert non-revised text.
builder.writeln("Deleted");
builder.write("Text");
// Remove first paragraph with tracking revisions.
doc.startTrackRevisions("author", new Date());
doc.getFirstSection().getBody().getFirstParagraph().remove();
doc.stopTrackRevisions();
Pattern regex = Pattern.compile("e", Pattern.CASE_INSENSITIVE);
FindReplaceOptions options = new FindReplaceOptions();
// Replace 'e' in document ignoring deleted text.
options.setIgnoreDeleted(true);
doc.getRange().replace(regex, "*", options);
System.out.println(doc.getText()); // The output is: Deleted\rT*xt\f
// Replace 'e' in document NOT ignoring deleted text.
options.setIgnoreDeleted(false);
doc.getRange().replace(regex, "*", options);
System.out.println(doc.getText()); // The output is: D*l*t*d\rT*xt\f

自定义查找和替换操作

Aspose.Words提供了许多不同的properties来查找和替换文本,例如使用ApplyFontApplyParagraphFormats属性应用特定格式,使用UseSubstitutions属性替换模式中的替换等。

下面的代码示例演示如何突出显示文档中的特定单词:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java
// Highlight word "the" with yellow color.
FindReplaceOptions options = new FindReplaceOptions();
options.getApplyFont().setHighlightColor(Color.YELLOW);
// Replace highlighted text.
doc.getRange().replace("the", "the", options);

Aspose.Words允许您在替换操作期间使用IReplacingCallback接口创建和调用自定义方法。 您可能有一些用例,您需要自定义查找和替换操作,例如将正则表达式指定的文本替换为HTML标记,因此基本上您将应用replace与insertingHTML。

如果需要用HTML标记替换字符串,请应用IReplacingCallback接口自定义查找和替换操作,以便匹配在运行开始时与文档的匹配节点开始。 让我们提供几个使用IReplacingCallback的例子。

下面的代码示例演示如何替换为HTML指定的文本:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java
public static void ReplaceWithHtml() throws Exception {
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.writeln("Hello <CustomerName>,");
FindReplaceOptions options = new FindReplaceOptions();
options.setReplacingCallback(new ReplaceWithHtmlEvaluator());
doc.getRange().replace(Pattern.compile(" <CustomerName>,"), "", options);
//doc.getRange().replace(" <CustomerName>,", html, options);
// Save the modified document.
doc.save(dataDir + "Range.ReplaceWithInsertHtml.doc");
System.out.println("\nText replaced with meta characters successfully.\nFile saved at " + dataDir);
}
static class ReplaceWithHtmlEvaluator implements IReplacingCallback {
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();
// create Document Buidler and insert MergeField
DocumentBuilder builder = new DocumentBuilder((Document) e.getMatchNode().getDocument());
builder.moveTo(currentNode);
// Replace '<CustomerName>' text with a red bold name.
builder.insertHtml("<b><font color='red'>James Bond, </font></b>");e.getReplacement();
currentNode.remove();
//Signal to the replace engine to do nothing because we have already done all what we wanted.
return ReplaceAction.SKIP;
}
}

下面的代码示例演示如何突出显示绿色的正数和红色的负数:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java
// Replace and Highlight Numbers.
static class NumberHighlightCallback implements IReplacingCallback {
public int replacing (ReplacingArgs args) throws Exception {
Node currentNode = args.getMatchNode();
// Let replacement to be the same text.
args.setReplacement(currentNode.getText());
int val = currentNode.hashCode();
// Apply either red or green color depending on the number value sign.
FindReplaceOptions options = new FindReplaceOptions();
if(val > 0)
{
options.getApplyFont().setColor(Color.GREEN);
}
else
{
options.getApplyFont().setColor(Color.RED);
}
return ReplaceAction.REPLACE;
}
}

下面的代码示例演示如何为每行添加行号:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java
public static void TestLineCounter() throws Exception {
// Create a document.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
// Add lines of text.
builder.writeln("This is first line");
builder.writeln("Second line");
builder.writeln("And last line");
// Prepend each line with line number.
FindReplaceOptions opt = new FindReplaceOptions();
opt.setReplacingCallback(new LineCounterCallback());
doc.getRange().replace(Pattern.compile("[^&p]*&p"), "", opt);
doc.save(dataDir + "TestLineCounter.docx");
}
static class LineCounterCallback implements IReplacingCallback
{
private int mCounter = 1;
public int replacing(ReplacingArgs args) throws Exception {
Node currentNode = args.getMatchNode();
System.out.println(currentNode.getText());
args.setReplacement(mCounter++ +"."+ currentNode.getText());
return ReplaceAction.REPLACE;
}
}