Найти и заменить
Вы можете легко перемещаться по документу с помощью клавиатуры и мыши, но если вам нужно пролистать много страниц, поиск определенного текста в длинном документе займет довольно много времени. Если вы захотите заменить определенные символы или слова, которые вы использовали в документе, это займет больше времени. Функция “Найти и заменить” позволяет вам найти последовательность символов в документе и заменить ее другой последовательностью символов.
Aspose.Words позволяет найти в документе определенную строку или шаблон регулярного выражения и заменить его альтернативным вариантом без установки и использования дополнительных приложений, таких как Microsoft Word. Это ускорит выполнение многих задач по набору текста и форматированию, что потенциально сэкономит вам часы работы.
В этой статье объясняется, как применять замену строк и регулярные выражения с поддержкой метасимволов.
Способы поиска и замены
Aspose.Words предоставляет два способа применить операцию поиска и замены, используя следующие:
- Simple string replacement – чтобы найти и заменить определенную строку на другую, вам необходимо указать строку поиска (буквенно-цифровые символы), которая будет заменена в соответствии со всеми совпадениями с другой указанной строкой замены. Обе строки не должны содержать символов. Примите во внимание, что сравнение строк может быть чувствительным к регистру, или вы можете быть не уверены в правильности написания, или у вас может быть несколько похожих вариантов написания.
- Regular expressions – чтобы задать регулярное выражение для поиска точных совпадений строк и замены их в соответствии с вашим регулярным выражением. Обратите внимание, что слово определяется как состоящее только из буквенно-цифровых символов. Если при замене совпадают только целые слова, а входная строка содержит символы, то фразы найдены не будут.
Кроме того, вы можете использовать специальные метасимволы с простой заменой строк и регулярные выражения для указания разрывов в рамках операции поиска и замены.
Aspose.Words представляет функциональность поиска и замены в пространстве имен Aspose.Words.Replacing. В процессе поиска и замены вы можете работать со многими параметрами, используя класс FindReplaceOptions.
Найдите и замените текст с помощью простой замены строки
Вы можете использовать один из методов Replace, чтобы найти или заменить определенную строку и вернуть количество выполненных замен. В этом случае вы можете указать строку, подлежащую замене, строку, которая заменит все свои вхождения, будет ли замена чувствительна к регистру и будут ли затронуты только отдельные слова.
В следующем примере кода показано, как найти строку “CustomerName” и заменить ее строкой “Джеймс Бонд”.:
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
// Load a Word Docx document by creating an instance of the Document class. | |
auto doc = System::MakeObject<Document>(); | |
auto builder = System::MakeObject<DocumentBuilder>(doc); | |
builder->Writeln(u"Hello _CustomerName_, "); | |
// Specify the search string and replace string using the Replace method. | |
doc->get_Range()->Replace(u"_CustomerName_", u"James Bond", System::MakeObject<FindReplaceOptions>()); | |
// Save the result. | |
System::String outputPath = outputDataDir + u"Range.ReplaceSimple.docx"; | |
doc->Save(outputPath); |
Вы можете заметить разницу между документами, прежде чем применять простую замену строк:
![before-simple-string-replacement-aspose-words-cpp](before-simple-string-replacement.png)
И после применения простой замены строки:
![after-simple-string-replacement-aspose-words-cpp](after-simple-string-replacement.png)
Поиск и замена текста с помощью регулярных выражений
Регулярное выражение (regex) - это шаблон, который описывает определенную последовательность текста. Предположим, вы хотите заменить все двойные вхождения слова одним вхождением слова. Затем вы можете применить следующее регулярное выражение для указания шаблона из двух слов: ([a-zA-Z]+) \1
.
Используйте другой метод Replace для поиска и замены определенных комбинаций символов, установив параметр Regex
в качестве шаблона регулярного выражения для поиска совпадений.
В следующем примере кода показано, как заменить строки, соответствующие шаблону регулярного выражения, указанной заменяющей строкой:
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
System::SharedPtr<Document> doc = System::MakeObject<Document>(); | |
auto builder = System::MakeObject<DocumentBuilder>(doc); | |
builder->Writeln(u"sad mad bad"); | |
System::SharedPtr<FindReplaceOptions> options = System::MakeObject<FindReplaceOptions>(); | |
// Replaces all occurrences of the words "sad" or "mad" to "bad". | |
doc->get_Range()->Replace(System::MakeObject<System::Text::RegularExpressions::Regex>(u"[s|m]ad"), u"bad", options); | |
const System::String outputPath = outputDataDir + u"FindAndReplaceWithRegex_out.doc"; | |
doc->Save(outputPath); |
Вы можете заметить разницу между документами, прежде чем применять замену строк регулярными выражениями:
![before-replacement-with-regular-expressions-aspose-words-cpp](before-replacement-with-regular-expressions.png)
И после применения замены строк регулярными выражениями:
![after-replacement-with-regular-expressions-aspose-words-cpp](after-replacement-with-regular-expressions.png)
Найдите и замените строку с помощью метасимволов
Вы можете использовать метасимволы в строке поиска или в строке замены, если определенный текст или фраза состоят из нескольких абзацев, разделов или страниц. Некоторые из метасимволов включают &p для обозначения разрыва абзаца, &b для обозначения разрыва раздела, &m для обозначения разрыва страницы и &l для обозначения разрыва строки.
В следующем примере кода показано, как заменить текст абзацем и разрывом страницы:
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
System::SharedPtr<Document> doc = System::MakeObject<Document>(); | |
System::SharedPtr<DocumentBuilder> builder = System::MakeObject<DocumentBuilder>(doc); | |
builder->get_Font()->set_Name(u"Arial"); | |
builder->Writeln(u"First section"); | |
builder->Writeln(u" 1st paragraph"); | |
builder->Writeln(u" 2nd paragraph"); | |
builder->Writeln(u"{insert-section}"); | |
builder->Writeln(u"Second section"); | |
builder->Writeln(u" 1st paragraph"); | |
System::SharedPtr<FindReplaceOptions> options = System::MakeObject<FindReplaceOptions>(); | |
options->get_ApplyParagraphFormat()->set_Alignment(ParagraphAlignment::Center); | |
// Double each paragraph break after word "section", add kind of underline and make it centered. | |
int32_t count = doc->get_Range()->Replace(u"section&p", u"section&p----------------------&p", options); | |
// Insert section break instead of custom text tag. | |
count = doc->get_Range()->Replace(u"{insert-section}", u"&b", options); | |
System::String savePath = outputDataDir + u"FindReplaceUsingMetaCharacters.ReplaceTextContaingMetaCharacters.docx"; | |
doc->Save(savePath); |
Найти и заменить строку в верхнем/нижнем колонтитуле документа
Вы можете найти и заменить текст в верхнем и нижнем колонтитулах документа Word, используя класс HeaderFooter.
В следующем примере кода показано, как заменить текст раздела заголовка в вашем документе:
Вы можете заметить разницу между документами до применения замены строки заголовка:
![before-applying-header-string-replacement-aspose-words-cpp](before-applying-header-string-replacement.png)
И после применения замены строки заголовка:
![after-applying-header-string-replacement-aspose-words-cpp](after-applying-header-string-replacement.png)
Пример кода для замены текста нижнего колонтитула в вашем документе очень похож на предыдущий пример кода верхнего колонтитула. Все, что вам нужно сделать, это заменить следующие две строки:
auto header = headersFooters->idx_get(HeaderFooterType::HeaderPrimary);
header->get_Range()->Replace(u"Aspose.Words", u"Remove", options);
Со следующим:
auto footer = headersFooters->idx_get(HeaderFooterType::FooterPrimary);
footer->get_Range()->Replace(u"(C) 2006 Aspose Pty Ltd.", u"Copyright (C) Aspose Pty Ltd.", options);
Вы можете заметить разницу между документами до того, как примените замену строки нижнего колонтитула:
![before-applying-footer-string-replacement-aspose-words-cpp](before-applying-footer-string-replacement.png)
И после применения замены строки нижнего колонтитула:
![after-applying-footer-string-replacement-aspose-words-cpp](after-applying-footer-string-replacement.png)
Игнорировать текст во время поиска и замены
Применяя операцию поиска и замены, вы можете игнорировать определенные фрагменты текста. Таким образом, определенные части текста могут быть исключены из поиска, а поиск и замена могут быть применены только к оставшимся частям.
Aspose.Words предоставляет множество свойств поиска и замены для игнорирования текста, таких как IgnoreDeleted, IgnoreFieldCodes, IgnoreFields, IgnoreFootnotes, и IgnoreInserted.
В следующем примере кода показано, как игнорировать текст внутри изменений удаления:
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
System::SharedPtr<Document> doc = System::MakeObject<Document>(); | |
System::SharedPtr<DocumentBuilder> builder = System::MakeObject<DocumentBuilder>(doc); | |
// Insert non-revised text. | |
builder->Writeln(u"Deleted"); | |
builder->Write(u"Text"); | |
// Remove first paragraph with tracking revisions. | |
doc->StartTrackRevisions(u"John Doe", System::DateTime::get_Now()); | |
doc->get_FirstSection()->get_Body()->get_FirstParagraph()->Remove(); | |
doc->StopTrackRevisions(); | |
System::SharedPtr<FindReplaceOptions> options = System::MakeObject<FindReplaceOptions>(); | |
// Replace 'e' in document while deleted text. | |
options->set_IgnoreDeleted(true); | |
doc->get_Range()->Replace(System::MakeObject<Regex>(u"e"), u"*", options); | |
std::cout << doc->GetText().ToUtf8String() << std::endl; // The output is: Deleted\rT*xt\f | |
// Replace 'e' in document NOT ignoring deleted text. | |
options->set_IgnoreDeleted(false); | |
doc->get_Range()->Replace(System::MakeObject<Regex>(u"e"), u"*", options); | |
std::cout << doc->GetText().ToUtf8String() << std::endl; // The output is: D*l*t*d\rT*xt\f |
Настройка операции поиска и замены
Aspose.Words предоставляет множество различных properties способов поиска и замены текста, таких как применение определенного формата со свойствами ApplyFont и ApplyParagraphFormats, использование подстановок в шаблонах замены со свойством UseSubstitutions и другие.
В следующем примере кода показано, как выделить определенное слово в вашем документе:
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
// Highlight word "the" with yellow color. | |
auto options = System::MakeObject<FindReplaceOptions>(); | |
options->get_ApplyFont()->set_HighlightColor(System::Drawing::Color::get_Yellow()); | |
// Replace highlighted text. | |
doc->get_Range()->Replace(u"Hello", u"Hello", options); |
Aspose.Words позволяет использовать интерфейс IReplacingCallback для создания и вызова пользовательского метода во время операции замены. Возможно, у вас есть некоторые варианты использования, когда вам нужно настроить операцию поиска и замены, например, заменить текст, указанный в регулярном выражении, тегами HTML, поэтому в основном вы будете применять замену с помощью вставки HTML.
Если вам нужно заменить строку HTML-тегом, примените интерфейс IReplacingCallback, чтобы настроить операцию поиска и замены таким образом, чтобы сопоставление начиналось в начале выполнения с узла сопоставления вашего документа. Приведем несколько примеров использования IReplacingCallback.
В следующем примере кода показано, как заменить текст, указанный в HTML:
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
class ReplaceWithHtmlEvaluator : public IReplacingCallback | |
{ | |
typedef ReplaceWithHtmlEvaluator ThisType; | |
typedef IReplacingCallback BaseType; | |
typedef ::System::BaseTypesInfo<BaseType> ThisTypeBaseTypesInfo; | |
RTTI_INFO(ThisType, ThisTypeBaseTypesInfo); | |
public: | |
ReplaceWithHtmlEvaluator(System::SharedPtr<FindReplaceOptions> options); | |
ReplaceAction Replacing(System::SharedPtr<ReplacingArgs> args) override; | |
private: | |
System::SharedPtr<FindReplaceOptions> mOptions; | |
}; | |
ReplaceWithHtmlEvaluator::ReplaceWithHtmlEvaluator(System::SharedPtr<FindReplaceOptions> options) | |
{ | |
mOptions = options; | |
} | |
ReplaceAction ReplaceWithHtmlEvaluator::Replacing(System::SharedPtr<ReplacingArgs> args) | |
{ | |
System::SharedPtr<DocumentBuilder> builder = System::MakeObject<DocumentBuilder>(System::DynamicCast<Document>(args->get_MatchNode()->get_Document())); | |
builder->MoveTo(args->get_MatchNode()); | |
// Replace '<CustomerName>' text with a red bold name. | |
builder->InsertHtml(u"<b><font color='red'>James Bond, </font></b>"); | |
args->set_Replacement(u""); | |
return ReplaceAction::Replace; | |
} | |
void ReplaceWithHtml(System::String const& inputDataDir, System::String const& outputDataDir) | |
{ | |
auto doc = System::MakeObject<Document>(); | |
auto builder = System::MakeObject<DocumentBuilder>(doc); | |
builder->Writeln(u"Hello <CustomerName>,"); | |
auto options = System::MakeObject<FindReplaceOptions>(); | |
auto optionsReplacingCallback = System::MakeObject<ReplaceWithHtmlEvaluator>(options); | |
doc->get_Range()->Replace(new Regex(u" <CustomerName>,"), System::String::Empty, options); | |
// Save the modified document. | |
doc->Save(outputDataDir + u"Range.ReplaceWithInsertHtml.doc"); | |
} |
В следующем примере кода показано, как выделить положительные числа зеленым цветом, а отрицательные - красным:
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
// Replace and Highlight Numbers. | |
class NumberHighlightCallback : public IReplacingCallback | |
{ | |
typedef NumberHighlightCallback ThisType; | |
typedef IReplacingCallback BaseType; | |
typedef ::System::BaseTypesInfo<BaseType> ThisTypeBaseTypesInfo; | |
RTTI_INFO(ThisType, ThisTypeBaseTypesInfo); | |
public: | |
NumberHighlightCallback(System::SharedPtr<FindReplaceOptions> const& opt) | |
: mOpt(opt) { } | |
Aspose::Words::Replacing::ReplaceAction Replacing(System::SharedPtr<Aspose::Words::Replacing::ReplacingArgs> args) override | |
{ | |
// Let replacement to be the same text. | |
args->set_Replacement(args->get_Match()->get_Value()); | |
auto val = System::Convert::ToInt32(args->get_Match()->get_Value()); | |
// Apply either red or green color depending on the number value sign. | |
mOpt->get_ApplyFont()->set_Color(val > 0 ? System::Drawing::Color::get_Green() : System::Drawing::Color::get_Red()); | |
return ReplaceAction::Replace; | |
} | |
private: | |
System::SharedPtr<FindReplaceOptions> mOpt; | |
}; |
В следующем примере кода показано, как добавлять номер строки перед каждой строкой:
For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C | |
class LineCounterCallback : public IReplacingCallback | |
{ | |
typedef LineCounterCallback ThisType; | |
typedef IReplacingCallback BaseType; | |
typedef ::System::BaseTypesInfo<BaseType> ThisTypeBaseTypesInfo; | |
RTTI_INFO(ThisType, ThisTypeBaseTypesInfo); | |
public: | |
Aspose::Words::Replacing::ReplaceAction Replacing(System::SharedPtr<Aspose::Words::Replacing::ReplacingArgs> args) override | |
{ | |
std::cout << args->get_Match()->get_Value().ToUtf8String() << '\n'; | |
args->set_Replacement(System::String::Format(u"{0} {1}", mCounter++, args->get_Match()->get_Value())); | |
return ReplaceAction::Replace; | |
} | |
private: | |
int32_t mCounter = 1; | |
}; | |
void LineCounter(System::String const& inputDataDir, System::String const& outputDataDir) | |
{ | |
// Create a document. | |
auto doc = System::MakeObject<Document>(); | |
auto builder = System::MakeObject<DocumentBuilder>(doc); | |
// Add lines of text. | |
builder->Writeln(u"This is first line"); | |
builder->Writeln(u"Second line"); | |
builder->Writeln(u"And last line"); | |
// Prepend each line with line number. | |
auto opt = System::MakeObject<FindReplaceOptions>(); | |
opt->set_ReplacingCallback(System::MakeObject<LineCounterCallback>()); | |
doc->get_Range()->Replace(System::MakeObject<Regex>(u"[^&p]*&p"), u"", opt); | |
doc->Save(outputDataDir + u"TestLineCounter.docx"); | |
} |