I am trying to write some code that changes a string like “/path/file.extension” to another specified extension. I am trying to use boost::xpressive to do so. But, I am having problems. It appears that a garbage character appears in the output:
#include <iostream>
#include <boost/xpressive/xpressive.hpp>
using namespace boost::xpressive;
using namespace std;
int main()
{
std::string str( "xml.xml.xml.xml");
sregex date = sregex::compile( "(\\.*)(\\.xml)$");
std::string format( "\1.zipxml");
std::string str2 = regex_replace( str, date, format );
std::cout << "str = " << str << "\n";
std::cout << "str2 = " << str2 << "\n";
return 0;
}
Now compile and run it:
[bitdiot@kantpute foodir]$ g++ badregex.cpp
[bitdiot@kantpute foodir]$ ./a.out > output
[bitdiot@kantpute foodir]$ less output
[bitdiot@kantpute foodir]$ cat -vte output
str = xml.xml.xml.xml$
str2 = xml.xml.xml^A.zipxml$
In the above example, I redirect output to a file, and use cat to print out the non-printable character. Notice the ctrl-A in the str2.
Anyways, am I using boost libraries incorrectly? Is this a boost bug? Is there another regular expression I can use that can allow me to string replace the “.tail” with some other string? (It’s fix in my example.)
thanks.
At least as I’m reading things, the culprit is right here:
std::string format( "\1.zipxml");.You forgot to escape the backslash, so
\1is giving you a control-A. You almost certainly want\\1.Alternatively (if your compiler is new enough) you could use a raw string instead, so it would be something like:
R"(\1.zipxml)", and you wouldn’t have to escape your backslashes. I probably wouldn’t bother to mention this, except for the fact that if you’re writing REs in C++ strings, raw strings are pretty much your new best friend (IMO, anyway).