也许我忽略了一些明显的东西,但我想知道在C中实现全字串替换的最快方法是什么.起初我考虑简单地将空格连接到搜索词,但这不考虑字符串边界或标点符号.
这是我目前对(非全字)替换的抽象:
void Replace(wstring& input,wstring find,wstring replace_with) {
if (find.empty() || find == replace_with || input.length() < find.length()) {
return;
}
for (size_t pos = input.find(find);
pos != wstring::npos;
pos = input.find(find,pos)) {
input.replace(pos,find.length(),replace_with);
pos += replace_with.length();
}
}
如果我只考虑空格作为单词边界,我可以通过比较搜索字符串的开头和结尾与查找字符串来覆盖字符串边界,然后用一个替换(L”找到L”)来实现这一点. ….但我想知道是否有一个更优雅的解决方案,有效地包括标点符号.
让我们考虑一个单词是由空格或标点符号分隔的任何字符集合(为了保持简单,让我们说吧!“#$%&'(*),– ./ at minimal – 恰好对应于( c> 31&& c< 48)). 在我的应用程序中,我必须在一个相当大的短字符串数组上调用此函数,其中可能包含各种Unicode,我不想拆分新单词.我还想避免包含任何外部库,但STL很好. 不使用正则表达式的目的是减少开销的承诺,以及适合于在大型数据集上执行此特定任务的快速函数的目标.
我认为你可以这样做,既可以进行全字匹配,又可以有效地进行.关键是:
>使用’std :: isalpha’检测“全字”边界,这应该与Unicode&任何语言环境.
>通过创建一个单独的“输出”字符串替换“out of place”,在处理结束时将其与“input”交换,而不是在“input”字符串本身上“就地”完成工作.
这是我对你的功能的看法:
#include <cctype> // isalpha
#include <ciso646> // or,not
#include <string> // wstring
using std::size_t;
using std::wstring;
/// @brief Do a "find and replace" on a string.
/// @note This function does "whole-word" matching.
/// @param[in,out] input_string The string to operate on.
/// @param[in] find_string The string to find in the input.
/// @param[in] replace_string The string to replace 'find_string'
/// with in the input.
void find_and_replace( wstring& input_string,const wstring& find_string,const wstring& replace_string )
{
if( find_string.empty()
or find_string == replace_string
or input_string.length() < find_string.length() )
{
return;
}
wstring output_string;
output_string.reserve( input_string.length() );
size_t last_pos = 0u;
for( size_t new_pos = input_string.find( find_string );
new_pos != wstring::npos;
new_pos = input_string.find( find_string,new_pos ) )
{
bool did_replace = false;
if( ( new_pos == 0u
or not std::isalpha( input_string.at( new_pos - 1u ) ) )
and ( new_pos + find_string.length() == input_string.length()
or not std::isalpha( input_string.at( new_pos + find_string.length() ) ) ) )
{
output_string.append( input_string,last_pos,new_pos - last_pos );
output_string.append( replace_string );
did_replace = true;
}
new_pos += find_string.length();
if( did_replace )
{
last_pos = new_pos;
}
}
output_string.append( input_string,input_string.length() - last_pos );
input_string.swap( output_string );
}
附:我不确定’replace_all’在你的初始例子中试图完成什么,所以为了清楚起见,我把它从我的解决方案中删除了.
P.P.S.使用Regex-es,这段代码会更清晰.你能依靠C TR1或C 2011功能吗?它们提供标准的“正则表达式”库.