#include <string>
#include <iostream>
int main() {
std::string to_search = "Some data with %MACROS to substitute";
std::string replace_with = "some very nice macros";
std::string macro_name;
std::cout << "Before: " << to_search << '\n';
std::string::size_type pos = 0;
while ((pos = to_search.find('%', pos)) != std::string::npos)
{
// Permit uppercase letters, lowercase letters and numbers in macro names
auto after = to_search.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", pos + 1);
// if no matching chars, set after past the last char...
if (after == std::string::npos)
after = to_search.size();
auto count = after - pos;
if (count > 1)
{
// extract the macro name and replace the macor only if
// the name actually maps to something worth replacing...
macro_name = to_search.substr(pos + 1, count - 1);
if (macro_name == "MACROS")
{
// found a macro!
to_search.replace(pos, count, replace_with);
// start the next search after the replaced text...
pos += replace_with.size();
continue;
}
// check for other macros as needed...
}
// no matching macro, skip the '%' and search again from the next char...
++pos;
}
std::cout << "After: " << to_search << '\n';
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKaW50IG1haW4oKSB7CiAgICBzdGQ6OnN0cmluZyB0b19zZWFyY2ggPSAiU29tZSBkYXRhIHdpdGggJU1BQ1JPUyB0byBzdWJzdGl0dXRlIjsKICAgIHN0ZDo6c3RyaW5nIHJlcGxhY2Vfd2l0aCA9ICJzb21lIHZlcnkgbmljZSBtYWNyb3MiOwogICAgc3RkOjpzdHJpbmcgbWFjcm9fbmFtZTsKCiAgICBzdGQ6OmNvdXQgPDwgIkJlZm9yZTogIiA8PCB0b19zZWFyY2ggPDwgJ1xuJzsKCiAgICBzdGQ6OnN0cmluZzo6c2l6ZV90eXBlIHBvcyA9IDA7CiAgICB3aGlsZSAoKHBvcyA9IHRvX3NlYXJjaC5maW5kKCclJywgcG9zKSkgIT0gc3RkOjpzdHJpbmc6Om5wb3MpCiAgICB7CiAgICAgICAgLy8gUGVybWl0IHVwcGVyY2FzZSBsZXR0ZXJzLCBsb3dlcmNhc2UgbGV0dGVycyBhbmQgbnVtYmVycyBpbiBtYWNybyBuYW1lcwogICAgICAgIGF1dG8gYWZ0ZXIgPSB0b19zZWFyY2guZmluZF9maXJzdF9ub3Rfb2YoIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5IiwgcG9zICsgMSk7CgogICAgICAgIC8vIGlmIG5vIG1hdGNoaW5nIGNoYXJzLCBzZXQgYWZ0ZXIgcGFzdCB0aGUgbGFzdCBjaGFyLi4uCiAgICAgICAgaWYgKGFmdGVyID09IHN0ZDo6c3RyaW5nOjpucG9zKQogICAgICAgICAgICBhZnRlciA9IHRvX3NlYXJjaC5zaXplKCk7CgogICAgICAgIGF1dG8gY291bnQgPSBhZnRlciAtIHBvczsKICAgICAgICBpZiAoY291bnQgPiAxKQogICAgICAgIHsKICAgICAgICAgICAgLy8gZXh0cmFjdCB0aGUgbWFjcm8gbmFtZSBhbmQgcmVwbGFjZSB0aGUgbWFjb3Igb25seSBpZgogICAgICAgICAgICAvLyB0aGUgbmFtZSBhY3R1YWxseSBtYXBzIHRvIHNvbWV0aGluZyB3b3J0aCByZXBsYWNpbmcuLi4KCiAgICAgICAgICAgIG1hY3JvX25hbWUgPSB0b19zZWFyY2guc3Vic3RyKHBvcyArIDEsIGNvdW50IC0gMSk7CiAgICAgICAgICAgIGlmIChtYWNyb19uYW1lID09ICJNQUNST1MiKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBmb3VuZCBhIG1hY3JvIQogICAgICAgICAgICAgICAgdG9fc2VhcmNoLnJlcGxhY2UocG9zLCBjb3VudCwgcmVwbGFjZV93aXRoKTsKCiAgICAgICAgICAgICAgICAvLyBzdGFydCB0aGUgbmV4dCBzZWFyY2ggYWZ0ZXIgdGhlIHJlcGxhY2VkIHRleHQuLi4KICAgICAgICAgICAgICAgIHBvcyArPSByZXBsYWNlX3dpdGguc2l6ZSgpOwoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBjaGVjayBmb3Igb3RoZXIgbWFjcm9zIGFzIG5lZWRlZC4uLgogICAgICAgIH0KCiAgICAgICAgLy8gbm8gbWF0Y2hpbmcgbWFjcm8sIHNraXAgdGhlICclJyBhbmQgc2VhcmNoIGFnYWluIGZyb20gdGhlIG5leHQgY2hhci4uLgogICAgICAgICsrcG9zOwogICAgfQoKICAgIHN0ZDo6Y291dCA8PCAiQWZ0ZXI6ICIgPDwgdG9fc2VhcmNoIDw8ICdcbic7Cn0=