概要
指定した文字列の範囲内のすべての文字列を指定した文字列に置換します。例:
ソース文字列:
“$START$dfh待到花开月圆时,两首相顾心相连。$END$dhussd2434xhuhu是别人十大海归。”
変換された文字列:
“dfh待到花开月圆时,两首相顾心相连。dhussd2434xhuhu是别人十大海归。”
または次のように変換されます。
“dhussd2434xhuhu是别人十大海归。”
この記事では、上記の文字列をうまく置き換える方法を記録します。このうち、変換後の最初の文字列は実際に元の文字列を(空文字列)“$START$”
に“$END$”
置き換えるもので、2番目は元の文字列内の文字列を に置き換えるものです。“”
“$START$”
“$END$”
“”
実装コード
void replaceDynamicString(
const std::string &startStr, const std::string &endStr,
const std::string &replacedStr,std::string &info, int start)
{
int startPos = info.find(startStr, start);
int endPos = info.find(endStr, start);
bool toBeReplace = false;
if (std::string::npos != startPos && std::string::npos != endPos &&
startPos < endPos)
{
toBeReplace = true;
int startStrSize = startStr.size();
int endStrSize = endStr.size();
std::string subKeyStr = info.substr(startPos + startStrSize,
endPos - startStrSize - startPos);
if (subKeyStr.size() != 0)
{
info.replace(startPos, endPos + endStrSize - startPos, replacedStr);
start = startPos + replacedStr.size();
}
else
start = endPos + endStrSize;
}
if (toBeReplace)
replaceDynamicString(startStr, endStr, replacedStr, info,start);
}
パラメータの説明
const std::string &startStr //置換文字列の開始位置、この例では
“$START$”
const std::string &endStr //置換文字列の終了位置、この例では“$END$”
const std::string &replacedStr //次のように置換されますreplaceStr 文字列、この例では“”
std::string &info //source string
int start //検索を開始する位置、この例では 0
関数呼び出し
電話する
QString strStart = "$PLAQUE_START$";
QString strEnd = "$PALQUE_END$";
QString strSourceMsg = "$START$dfh待到花开月圆时,两首相顾心相连。$END$dhussd2434xhuhu是别人十大海归。";
std::string strTempMsg = strSourceMsg.toStdString();
replaceDynamicString(strStart.toStdString(),
strEnd.toStdString(), "",
strTempMsg, 0);
電話の結果
呼び出し後の文字列 strTempMsg の結果は次のようになります。
dhussd2434xhuhu は、他の人のトップ 10 の帰国者です。
二人に電話する
QString strStart = "$PLAQUE_START$";
QString strEnd = "$PALQUE_END$";
QString strSourceMsg = "$START$dfh待到花开月圆时,两首相顾心相连。$END$dhussd2434xhuhu是别人十大海归。";
strSourceMsg.replace(strStart , "").replace(strEnd , "");
通話結果
通話が終了すると、文字列 strSourceMsg の結果は次のようになります。
dfh 花が咲き、月が満月になると、2 人の首相が結ばれます。dhussd2434xhuhu は他の人の帰国子女トップ 10 です。
知らせ
上記の呼び出し例で、文字列を置換した後もソース文字列を変更しないようにしたい場合は、置換前のソース文字列を一時的に保存し、置換後に再度ソース文字列変数に代入する必要があります。
3人に電話する
ソース文字列「dhus Hudhan Fans, START START」を配置します花が咲き、月が満月になると、二人の首相はお互いを思いやる。終わり 終わりEN D dhussd2434xhuhu は他の人の帰国子女トップ 10 です。フーダンファンサの場所に「変更されました」。dhussd2434xhuhu は他の人の帰国子女トップ 10 です。上記
の要件を満たすために、上記の置換関数で追加されたカンマをピリオドコードに置き換える必要があります。変更された置換関数は次のとおりです。
void ReportManager::replaceDynamicString(const std::string &startStr,
const std::string &endStr,
const std::string &replacedStr,
std::string &info, int start)
{
int startPos = info.find(startStr, start);
int endPos = info.find(endStr, start);
bool toBeReplace = false;
if (std::string::npos != startPos && std::string::npos != endPos &&
startPos < endPos)
{
toBeReplace = true;
int startStrSize = startStr.size();
int endStrSize = endStr.size();
std::string subKeyStr = info.substr(startPos + startStrSize,
endPos - startStrSize - startPos);
if (subKeyStr.size() != 0)
{
info.replace(startPos, endPos + endStrSize - startPos, replacedStr);
// after replace "$xxxx$" contain description msg,if prevoius pos is
// ",",replace to be "."
LOG_INFO("--->startPos:", info[startPos]);
LOG_INFO("--->startPos + 1:", info[startPos + 1]);
LOG_INFO("--->startPos - 2:", info[startPos - 2]);
LOG_INFO("--->startPos-1", info[startPos - 1]);
LOG_INFO("--->BEFORE CHARATER:", info[startPos - 1], "info:", info);
// char c = m_translate.strCommas.toStdString();
/* std::string str = info.substr(startPos-1,1);
LOG_INFO("--->str:",str);*/
if (info.rfind(",", startPos) != string::npos ||
info.rfind(",", startPos) !=
string::npos) // m_translate.strCommas.toStdString())//','
{
int nPos = 0;
esApp->getAppConfig()->getIsChinese() // 判断是否为中文,esApp->getAppConfig()->getIsChinese(),这句代码是当时项目上的,不能照搬,明白大意即可
? nPos = info.rfind(",", startPos)
: nPos = info.rfind(",", startPos);
info.replace(nPos, startPos - nPos,
m_translate.strPeriod.toStdString());//这句将逗号替换为句号,因为引入了qt的多语言,m_translate.strPeriod代表句号,此句也不能照搬,理解大意即可
}
start = startPos + replacedStr.size();
}
else
start = endPos + endStrSize;
}
if (toBeReplace)
replaceDynamicString(startStr, endStr, replacedStr, info, start);
}
上記の置換関数で変更した部分は、実際には置換対象の識別子の前のカンマをピリオドに変更することを実現しています。中国語か英語のカンマかの判定を追加しました。
上記の変更後、置換関数 replaceDynamicString が次のように呼び出されます。
QString strStart = "$PLAQUE_START$";
QString strEnd = "$PALQUE_END$";
QString strSourceMsg = "dhus胡但凡撒地方,$START$dfh待到花开月圆时,两首相顾心相连。$END$dhussd2434xhuhu是别人十大海归。";
std::string strTempMsg = strSourceMsg.toStdString();
replaceDynamicString(strStart.toStdString(),
strEnd.toStdString(), "",
strTempMsg, 0);
通話結果
通話が終了すると、文字列 strTempMsg の結果は次のようになります。dhus
Hu Dan Fansa の場所、dhussd2434xhuhu は他の人のトップ 10 の帰国者です。
知らせ
文字列も翻訳できる場合、つまりqtの多言語化が導入されている場合、この多言語文字列の句読点の置き換えには多言語の考え方を使って判断する必要があり、オフセットは使えません(つまり、句読点の次の位置 -1 という考え)、中国語文字列内の漢字は 1 つではありません。